如何通过PHP Webhook向DialogFlow发送数组格式响应?
Problem Description
I'm building a chatbot with Dialogflow and using a custom PHP webhook to generate responses. I'm fetching data from a database and storing it in an array, but when sending the array as a response to Dialogflow, only the first row of data is displayed. I've confirmed the query returns multiple results, but Dialogflow only shows the first one.
Here's my code:
<?php header('Content-Type: text/html; charset=utf-8'); date_default_timezone_set("Asia/Bangkok"); $date = date("Y-m-d"); $time = date("H:i:s"); $json = file_get_contents('php://input'); $request = json_decode($json, true); $input = fopen("log_json.txt", "w") or die("Unable to open file!"); fwrite($input,$json); fclose($input); function processMessage($update) { if($update["queryResult"]["action"] == "ques"){ $bdd= new PDO('mysql:host=localhost;dbname=****', '****', '***', array( PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")) ; $data = array(); $nom= $update["queryResult"]["parameters"]["nom_aliment"]; $info=$update["queryResult"]["parameters"]["Information"]; $quantite=$update["queryResult"]["parameters"]["Quantite"]; $req=$bdd->prepare("SELECT * FROM TableCiqual WHERE alim_nom LIKE ? "); $req->execute(array("%$nom%")); while($resultat=$req->fetch()){ $variab=$resultat[$info]*$quantite/100; $ppp =$resultat['alim_nom'].' '.$info.' : '.$variab; $data=$ppp; // This is the critical issue! } sendMessage(array( "source" => $update["responseId"], "fulfillmentText"=>$data, "payload" => array( "items"=>[ array( "simpleResponse"=> array( "textToSpeech"=>"Bad request" ) ) ], ), )); } } function sendMessage($parameters) { echo json_encode($parameters); }
Can I send an array response to Dialogflow? If yes, how should I implement this?
Answer
Hey there, let's fix this issue step by step. The core problem in your code is how you're handling the $data variable inside the while loop:
$data=$ppp;
This line overwrites $data with the current row's string every time the loop runs. By the end of the loop, $data only holds the last result (you might have mixed up first/last, but regardless, it's not collecting all your database rows).
Yes, you can send multiple results to Dialogflow—you just need to format the response correctly. Here are two practical approaches:
1. Combine Results into a Single String (Simplest Solution)
First, collect all results into an array, then join them into a single string with separators like newlines or bullet points. Dialogflow will display this as one message with all your results.
Modify your loop and response like this:
function processMessage($update) { if($update["queryResult"]["action"] == "ques"){ $bdd= new PDO('mysql:host=localhost;dbname=****', '****', '***', array( PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")) ; $data = array(); // Initialize empty array to collect results $nom= $update["queryResult"]["parameters"]["nom_aliment"]; $info=$update["queryResult"]["parameters"]["Information"]; $quantite=$update["queryResult"]["parameters"]["Quantite"]; $req=$bdd->prepare("SELECT * FROM TableCiqual WHERE alim_nom LIKE ? "); $req->execute(array("%$nom%")); while($resultat=$req->fetch()){ $variab=$resultat[$info]*$quantite/100; $ppp =$resultat['alim_nom'].' '.$info.' : '.$variab; $data[] = $ppp; // Add each result to the array instead of overwriting } // Join array into a single string with newlines $fulfillmentText = implode("\n", $data); // Add fallback message if no results are found if(empty($fulfillmentText)) { $fulfillmentText = "No results found for that query."; } sendMessage(array( "source" => $update["responseId"], "fulfillmentText"=>$fulfillmentText, "payload" => array( "items"=>[ array( "simpleResponse"=> array( "textToSpeech"=> $fulfillmentText // Match text-to-speech to the displayed text ) ) ], ), )); } }
2. Use Rich Responses (Multiple Separate Messages)
If you want each result to appear as a separate message or use formatted elements like lists, you can build a rich response in the payload field. For example, adding multiple simpleResponse items:
function processMessage($update) { if($update["queryResult"]["action"] == "ques"){ $bdd= new PDO('mysql:host=localhost;dbname=****', '****', '***', array( PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")) ; $responseItems = array(); $nom= $update["queryResult"]["parameters"]["nom_aliment"]; $info=$update["queryResult"]["parameters"]["Information"]; $quantite=$update["queryResult"]["parameters"]["Quantite"]; $req=$bdd->prepare("SELECT * FROM TableCiqual WHERE alim_nom LIKE ? "); $req->execute(array("%$nom%")); while($resultat=$req->fetch()){ $variab=$resultat[$info]*$quantite/100; $text = $resultat['alim_nom'].' '.$info.' : '.$variab; // Add each result as a separate simpleResponse $responseItems[] = array( "simpleResponse" => array( "textToSpeech" => $text, "displayText" => $text ) ); } // Handle empty results if(empty($responseItems)) { $responseItems[] = array( "simpleResponse" => array( "textToSpeech" => "No results found for that query.", "displayText" => "No results found for that query." ) ); } sendMessage(array( "source" => $update["responseId"], "fulfillmentText"=> implode("\n", array_column(array_column($responseItems, 'simpleResponse'), 'displayText')), // Fallback text for platforms that don't support rich responses "payload" => array( "items" => $responseItems ), )); } }
Key Notes:
- Dialogflow's
fulfillmentTextexpects a single string, not an array—passing an array directly will result in a uselessArraystring being displayed. - The
payloadfield lets you send platform-specific rich responses (like multiple messages, cards, or lists) depending on the chat platform you're using (Google Assistant, Facebook Messenger, etc.). - Always handle empty result cases to avoid sending blank responses to users.
内容的提问来源于stack exchange,提问作者Pastheque146

