So I have an array and form with input where I put an ID that should show the corresponding row from the array.
So far I have made this:
<?php
$file = 'people.txt';
$people = array();
$ref = fopen($file, 'r');
while ($row = fgets($ref, 1024)) {
$row = explode("|", $row);
$id = $row[0];
$name = $row[1];
$status = $row[2];
$people[$id] = array('name' => $name, 'status' => $status);
}
fclose($ref);
foreach($people as $id => $person) {
if($_GET[person]==$id && $person[status]==1) {
echo $person[name] . "(" . $id . "): ready";
}
if($_GET[person]==$id && $person[status]==0) {
echo $person[name] . "(" . $id . "): not ready";
}
if($_GET[person]!=$id) {
echo "Person with this ID was not found";
}
}
?>
This shows the correct info of searched ID, but it also shows "person was not found" to every other person in the array. How can I get it to show only the person that matches the input?
There's no need AT ALL for the loop. If you already have the ID of the person, then there's no need to scan the array for that id, just use it directly:
if (isset($people[$id])) {
... do stuff with person # $id
} else {
... person does not exist
}
Unless you need the array of all the people for some other purpose after this code, you can get only the person indicated by $_GET['person'] from the file. Just add a check inside the while loop.
$person = null; // initialize person
$ref = fopen($file, 'r');
while ($row = fgets($ref, 1024)) {
$row = explode("|", $row);
if ($row[0] == $_GET['person']) { // only get rows that match the searched id
$person = array('name' => $row[1], 'status' => $row[2]);
}
}
fclose($ref);
This will reduce the memory usage of your script by avoiding creating an array of the entire file. The benefit of this obviously depends on the size of the file.
(Even if you do need the entire array, you can still set $person in an if block in your while loop at the same time you are filling the $people array.)
Then after that loop, $person will be just one thing: either an array with the last matched row in your file, or null. That means you won't have to find it in an array; you can output the status information like this:
if ($person) {
echo "$person[name] ($person_id): ";
echo $person['status'] ? 'ready' : 'not ready';
} else {
echo "Person with this ID was not found";
}
Since you are only searching for one "person ID", you do not need the second foreach loop in your code. I recommend refactoring a bit to include more error checking and also reading about type juggling and casting in PHP.
I've modified your code to include some hints that should point you in the right direction:
<?php
$file = 'people.txt';
$people = array();
$ref = fopen($file, 'r');
while ($row = fgets($ref, 1024)) {
$row = explode('|', $row);
if (!isset($row[0]) || !isset($row[1]) || !isset($row[2])) {
continue;
}
$id = (int) $row[0];
$name = (string) $row[1];
$status = (int) $row[2];
$people[$id] = array('name' => $name, 'status' => $status);
}
fclose($ref);
$id = array_key_exists('person', $_GET) ? $_GET['person'] : null;
if (array_key_exists($id, $people)) {
$person = $people[$id];
if ($person['status'] === 1) {
echo $person['name'] . ' (' . $id . '): ready';
} else {
echo $person['name'] . ' (' . $id . '): not ready';
}
} else {
echo 'Person with ID ' . htmlspecialchars($id) . ' not found';
}
If you plan on people.txt becoming large in size, consider storing the data in a database such as MySQL. This will eliminate having to read the contents of the file into memory on every request.
Use a boolean variable to detect if the person you're searching for is found or not, The code could be like this:
$found = false;
foreach($people as $id => $person) {
if($_GET[person]==$id) {
$found = true;
if($person[status]==1)
echo $person[name] . "(" . $id . "): ready";
else if($person[status]==0)
echo $person[name] . "(" . $id . "): not ready";
//You can (break;) here if you're sure that the $id is identical
}
}
if($found == false)
echo "Person with this ID was not found";
Related
I managed to add multiple data in one column in the database, but now I need to display it with a new line in the browser so they don't stick with each other as I display them as an array in one column.
Here is my code:
if (isset($_GET['id']) && $_GET['id'] == 5) {
$subArray = array("StudentAnswer");
$subId6 = $db->get("answertable", null, $subArray);
foreach ($subId6 as $sub) {
$answers[] = $sub['StudentAnswer'] . "\n";
}
foreach ($answers as $row) {
$answers2 = explode("||", $row[0]);
foreach($answers2 as $row2){
$answers3 = $row2 . '\n';
}
}
$db->where('AccessId', $_GET['token']);
$db->where('StudentAnswer', $answers3);
$subId8 = $db->get("answertable");
if ($subId8) {
echo json_encode($subId8);
}
}
You are overriding $subId6 after getting its content. Try to fetch the table $rows in a new variable and the extract the content from it, like the code below.
<?php
// Example of $subId6 content
$subId6 = array(["StudentAnswer" => ["Answer 1\nAnswer 2\nAnswer 3"]], ["StudentAnswer" => ["Answer 1\nAnswer 2\nAnswer 3"]]);
// Fetch rows
foreach ($subId6 as $sub) {
$rows[] = $sub['StudentAnswer'];
}
// Decode rows
foreach($rows as $row) {
$answers = explode("\n", $row[0]);
echo "New answers: \n";
// Split answers in single answer
foreach ($answers as $answer)
echo "$answer \n";
echo "\n";
}
You will have a list of all the answers split for table rows
If you want a string of answers seperated by a space then simply do
if (isset($_GET['id']) && $_GET['id'] == 5) {
$subId6 = $db->get("answertable");
foreach ($subId6 as $sub) {
$answers .= $sub['StudentAnswer'] . ' ';
}
$answers= rtrim($answers, ' '); //remove last space in case thats an issue later
$db->where('AccessId', $_GET['token']);
$db->where('StudentAnswer', $answers);
$subId8 = $db->get("answertable");
if ($subId8) {
echo json_encode($subId8);
}
}
I am getting the result from web service SOAP client. I have created an array to get the result and display it using json format. I am getting few of my results properly. I have SerialEquipment parameter which is array and i need to get the result using foreach loop. I am doing an mistake there. I dont know how can i assign my $vehiclResult array in this for each statement. So that all the results at last i will collect and display using json using vehicleResult array.My mistake is in the foreach loop.
structure for SerialEquipment parameters:
Code:
$vehicle = getVehicleValuation();
$Serial=$vehicle['SerialEquipment'];
$vehiclResult = array(
'WE_Number' => $vehicle['WE Number'] ."<br>",
'Vehicle Type'=> $vehicle['Vehicle Type'] . "<br>",
'HSN' => $vehicle['HSN'] . "<br>",
'TSN' => $vehicle['TSN'] . "<br>"
);
foreach($Serial as $key => $obj) {
if(!isset($vehiclResult[$key]))
$vehiclResult[$key] = array();
$vehiclResult[$key]['SerialEquipment'] = $key. "<br>";
$vehiclResult[$key]['Code'] = $obj->Code. "<br>";
$vehiclResult[$key]['Desc Short'] = $obj->Desc_Short. "<br>";
$vehiclResult[$key]['Desc Long'] = $obj->Desc_Long. "<br>";
foreach($obj->Esaco as $key2 => $obj2) {
if($obj2->EsacoMainGroupCode === null){
// doesn't contain Esaco
continue;
}
else{
if(!isset($vehiclResult[$key][$key2]))
$vehiclResult[$key][$key2] = array();
$vehiclResult[$key][$key2]['esaco'] = $key2. "<br>";
$vehiclResult[$key][$key2]['EsacoMainGroupCode'] = $obj2->EsacoMainGroupCode. "<br>";
$vehiclResult[$key][$key2]['EsacoMainGroupDesc'] = $obj2->EsacoMainGroupDesc. "<br>";
$vehiclResult[$key][$key2]['EsacoSubGroupCode'] = $obj2->EsacoSubGroupCode. "<br>";
$vehiclResult[$key][$key2]['EsacoSubGroupDesc'] = utf8_decode($obj2->EsacoSubGroupDesc). "<br>";
$vehiclResult[$key][$key2]['EsacoGroupCode'] = $obj2->EsacoGroupCode. "<br>";
$vehiclResult[$key][$key2]['EsacoGroupDesc'] = utf8_decode($obj2->EsacoGroupDesc). "<br>";
}
}
}
$result = array(
'vehicle' => $vehiclResult
);
echo json_encode($result);
die();
}
You need to check if your array have the key so:
if(!isset($vehiclResult[$key]))
if not, you need to create it:
$vehiclResult[$key] = array(); // as an array
Also, you don't really need to make a description of your "item". You can Parse your JSON on the result page to output some text.
You can do something like.
Do something like:
foreach($Serial as $key => $obj) {
if(!isset($vehiclResult[$key]))
$vehiclResult[$key] = array();
$vehiclResult[$key]['serial'] = $key;
$vehiclResult[$key]['code'] = $obj->Code;
$vehiclResult[$key]['short_desc'] = $obj->Desc_Short;
$vehiclResult[$key]['long_desc'] = $obj->Desc_Long;
foreach($obj->Esaco as $key2 => $obj2) {
if($obj2->EsacoMainGroupCode === null){
// doesn't contain Esaco
continue;
}
else{
if(!isset($vehiclResult[$key][$key2]))
$vehiclResult[$key][$key2] = array();
$vehiclResult[$key][$key2]['esaco'] = $key2;
$vehiclResult[$key][$key2]['EsacoMainGroupCode'] = $obj2->EsacoMainGroupCode;
$vehiclResult[$key][$key2]['EsacoMainGroupDesc'] = $obj2->EsacoMainGroupDesc;
$vehiclResult[$key][$key2]['EsacoSubGroupCode'] = $obj2->EsacoSubGroupCode;
$vehiclResult[$key][$key2]['EsacoSubGroupDesc'] = utf8_decode($obj2->EsacoSubGroupDesc);
$vehiclResult[$key][$key2]['EsacoGroupCode'] = $obj2->EsacoGroupCode;
$vehiclResult[$key][$key2]['EsacoGroupDesc'] = utf8_decode($obj2->EsacoGroupDesc);
}
}
}
$result = array(
'vehicle' => $vehiclResult
);
echo json_encode($result);
die();
If you would keep your "text" and your <br> code, do the samething but add what you want to output after the "="
EDIT
** A HAVE CHANGE THE CODE PREVIOUSLY..
if you want to test your $vehiclResult, try something like:
foreach($vehiclResult as $key=>$value){
if(!is_array($value))
var_dump($value);
else {
foreach($value as $key2=>$value2){
if(!is_array($value2))
var_dump($value2);
else {
foreach($value2 as $key3=>$value3){
var_dump($value3);
}
}
}
}
I'm making this function where a part of an array should be read, and each value holds a number with which I want to perform a PDO query. This is my following code:
function get_topics($array) {
$top = 20; $base = 0;
foreach ($array as $key => $value) {
$getData = $dbc->prepare('SELECT * FROM topics WHERE id = :id LIMIT 1');
$getData->execute(array(':id' => $value));
while($row = $getData->fetch()) {
$potential_topic_img = 'members/topic_' . $value . '.jpg';
if (file_exists($potential_topic_img)) { $topic_img = $potential_topic_img; } else {
$topic_img = 'members/0.jpg'; }
$name = $row['name'];
echo '<div class="topic_div"><img src="' . $topic_img . '" width="80"><br /><span
style="font-size:10pt;">' . $name . '</span></div>';
} if (++$base == $top) break;
}
}
echo get_topics($some_array);
But all I get is an error telling this: "Parse error: syntax error, unexpected T_VARIABLE in /home/......", and it says that the problem is on this line:
$getData->execute(array(':id' => $value));
What can I be doing wrong?
EDIT
I deleted some code and the code is running fine when this is remaining:
function get_topics($array) {
foreach ($array as $key => $value) {
echo $value;
}
}
echo get_topics($user_likes_array);
So it's not that $value is empty, the problem seems to be in the line I mentioned in the beginning, since when I move everything below that line, the error message does not change, but it does change when I move that specific line.
foreach ($array as $key => $value) assigns the current element's key to the $value variable on each iteration.
Try
$getData->execute(':id',$value);
The code you have posted is correct are you sure your in the right file.
I have just coped your code and sorted out the layout and ran it though my PHP Testing batch and it is correct
Output from testing batch
G:\Others\Programs\phpApplications>SET PHP_PATH=../php/php.exe
G:\Others\Programs\phpApplications>SET FILE_PATH=../phpApplications/test2.php
G:\Others\Programs\phpApplications>SET LOOP=FALSE
G:\Others\Programs\phpApplications>"../php/php.exe" "../phpApplications/test2.ph
p"
G:\Others\Programs\phpApplications>pause
Press any key to continue . . .
Code i used
<?php
function get_topics($array) {
$top = 20;
$base = 0;
foreach ($array as $key => $value) {
$getData = $dbc->prepare('SELECT * FROM topics WHERE id = :id LIMIT 1');
$getData->execute(array(':id' => $value));
while($row = $getData->fetch()) {
$potential_topic_img = 'members/topic_' . $value . '.jpg';
if (file_exists($potential_topic_img)) { $topic_img = $potential_topic_img; } else {
$topic_img = 'members/0.jpg'; }
$name = $row['name'];
echo '<div class="topic_div"><img src="' . $topic_img . '" width="80"><br /><span
style="font-size:10pt;">' . $name . '</span></div>';
}
if (++$base == $top) break;
}
}
$some_array = array();
echo get_topics($some_array);
if there was an error you would have seen it before the pause command is sent to CMD it would have shown the error
Proof My Tester Works
for this i just commented out // the $some_array = array() here is the result
G:\Others\Programs\phpApplications>SET PHP_PATH=../php/php.exe
G:\Others\Programs\phpApplications>SET FILE_PATH=../phpApplications/test2.php
G:\Others\Programs\phpApplications>SET LOOP=FALSE
G:\Others\Programs\phpApplications>"../php/php.exe" "../phpApplications/test2.ph
p"
Warning: Invalid argument supplied for foreach() in G:\Others\Programs\phpApplic
ations\test2.php on line 6
G:\Others\Programs\phpApplications>pause
Press any key to continue . . .
I want to display information from multiple rows. Without changing the majority of my code, how can I echo the multiple rows on my webpage that have user_id_offerer = '$offerer'. I did echo the mysql query and I got the result of Resource Id #14 and I understand a while loop is necessary, but it seems like there is a problem with mysql. How do I fix this?
Clarification: When I ran the code with the while loop, I received an infinite loop of the first row. I did not receive each individual row that had user_id_offerer = 'offerer'. How do I fix this without having to do a major re-write of the code.
function ergo_data ($offerer) {
$data = array();
$offerer = (int)$offerer;
$func_num_args = func_num_args();
$func_get_args = func_get_args();
if ($func_num_args > 1) {
unset($func_get_args[0]);
$fields ='`' . implode ('`, `', $func_get_args) . '`';
$data = mysql_fetch_assoc (mysql_query("SELECT $fields FROM `ergo` WHERE `user_id_offerer` = '$offerer'"));
return $data;
}
}
if (logged_in() === true) {
$session_user_id = $_SESSION['user_id'];
$ergo_data = ergo_data($session_user_id, 'primary_key', 'user_id_offerer', 'user_id_seeker', 'ergo', 'ergo_time_submitted');
}
echo $ergo_data['ergo'] . '<br>';
echo username_from_user_id($ergo_data['user_id_offerer']) . '<br>';
echo username_from_user_id($ergo_data['user_id_seeker']) . '<br>';
echo $ergo_data['ergo_time_submitted'];`
I think you need to return the result of mysql_query from your ergo_data() function (instead of the result of mysql_fetch_assoc), then call mysql_fetch_assoc in the loop:
// inside ergo_data(), change
// $data = mysql_fetch_assoc (mysql_query("SE ...
// to:
function ergo_data ($offerer) {
...
return mysql_query("SELECT $fields FROM `ergo`....");
}
...
if (logged_in() === true) {
$session_user_id = $_SESSION['user_id'];
$query_result = ergo_data($session_user_id, 'primary_key', 'user_id_offerer', 'user_id_seeker', 'ergo', 'ergo_time_submitted');
while($ergo_data = mysql_fetch_assoc($query_result)) {
echo $ergo_data['ergo'] . '<br>';
echo username_from_user_id($ergo_data['user_id_offerer']) . '<br>';
echo username_from_user_id($ergo_data['user_id_seeker']) . '<br>';
echo $ergo_data['ergo_time_submitted'];
}
}
Suppose I have a multi-dimensional array of the form:
array
(
array('Set_ID' => 1, 'Item_ID' => 17, 'Item_Name' = 'Whatever'),
array('Set_ID' => 1, 'Item_ID' => 18, 'Item_Name' = 'Blah'),
array('Set_ID' => 2, 'Item_ID' => 19, 'Item_Name' = 'Yo')
)
The array has more sub-arrays, but that's the basic form-- Items in Sets.
How can I loop through this array so that I can echo the number of items in each set along with the all the items like so:
Set 1 has 2 Items: 17: Whatever and 18: Blah
Set 2 has 1 Items: 19: Yo
I'm aware that this could be done with two loops-- one to build an array, and another to loop through that array. However, I'd like to do this all with only one loop.
In your answer, you should assume that there are two display functions
display_set($id, $count) //echo's "Set $id has $count Items"
display_item($id, $name) //echo's "$id: $name"
UPDATE: Forgot to mention that the data is sorted by Set_ID because its from SQL
Right, all the examples below rely on an ordered set, the OP states it is ordered initially, but if needed a sort function could be:
// Sort set in to order
usort($displaySet,
create_function('$a,$b',
'return ($a['Set_ID'] == $b['Set_ID']
? ($a['Set_ID'] == $b['Item_ID']
? 0
: ($a['Item_ID'] < $b['Item_ID']
? -1
: 1))
: ($a['Set_ID'] < $b['Set_ID'] ? -1 : 1));'));
Straight example using a single loop:
// Initialise for the first set
$cSetID = $displaySet[0]['Set_ID'];
$cSetEntries = array();
foreach ($displaySet as $cItem) {
if ($cSetID !== $cItem['Set_ID']) {
// A new set has been seen, display old set
display_set($cSetID, count($cSetEntries));
echo ": " . implode(" and ", $cSetEntries) . "\n";
$cSetID = $cItem['Set_ID'];
$cSetEntries = array();
}
// Store item display for later
ob_start();
display_item($cItem['Item_ID'], $cItem['Item_Name');
$cSetEntries[] = ob_get_clean();
}
// Perform last set display
display_set($cSetID, count($cSetEntries));
echo ": " . implode(" and ", $cSetEntries) . "\n";
Using a recursive function it could be something like this:
// Define recursive display function
function displayItemList($itemList) {
if (!empty($itemList)) {
$cItem = array_shift($itemList);
display_item($cItem['Item_ID'], $cItem['Item_Name');
if (!empty($itemList)) {
echo " and ";
}
}
displayItemList($itemList);
}
// Initialise for the first set
$cSetID = $displaySet[0]['Set_ID'];
$cSetEntries = array();
foreach ($displaySet as $cItem) {
if ($cSetID !== $cItem['Set_ID']) {
// A new set has been seen, display old set
display_set($cSetID, count($cSetEntries));
echo ": ";
displayItemList($cSetEntries);
echo "\n";
$cSetID = $cItem['Set_ID'];
$cSetEntries = array();
}
// Store item for later
$cSetEntries[] = $cItem;
}
// Perform last set display
display_set($cSetID, count($cSetEntries));
echo ": ";
displayItemList($cSetEntries);
echo "\n";
Amusingly, it can be one single recursive function:
function displaySetList($setList, $itemList = NULL) {
// First call, start process
if ($itemList === NULL) {
$itemList = array(array_shift($setList));
displaySetList($setList, $itemList);
return;
}
// Check for display item list mode
if ($setList === false) {
// Output first entry in the list
$cItem = array_shift($itemList);
display_item($cItem['Item_ID'], $cItem['Item_Name']);
if (!empty($itemList)) {
// Output the next
echo " and ";
displaySetList(false, $itemList);
} else {
echo "\n";
}
return;
}
if (empty($setList) || $setList[0]['Set_ID'] != $itemList[0]['Set_ID']) {
// New Set detected, output set
display_set($itemList[0]['Set_ID'], count($itemList));
echo ": ";
displaySetList(false, $itemList);
$itemList = array();
}
// Add next item and carry on
$itemList[] = array_shift($setList);
displaySetList($setList, $itemList);
}
// Execute the function
displaySetList($displaySet);
Note that the recursive example here is grossly inefficient, a double loop is by far the quickest.
<?php
$sets = array();
foreach ($items as $item)
{
if (!array_key_exists($item['Set_ID'], $sets))
{
$sets[$item['Set_ID']] = array();
}
$sets[$item['Set_ID']][] = $item;
}
foreach ($sets as $setID => $items)
{
echo 'Set ' . $setID . ' has ' . count($items) . ' Items: ';
foreach ($items as $item)
{
echo $item['Item_ID'] . ' ' . $item['Item_Name'];
}
}
?>
Something like this i guess?
EDIT:
After i posted this i saw the display functions where added. But you get the point.
The need to not print out any items until we know how many there are in the set makes this difficult. At some point, we'll need to doing some buffering, or else backtracking. However, if I'm allowed internal loops, and sets are contiguous in the "master" array, then with some hacking around:
$set = 0;
$items;
foreach ($arr as $a) {
if ($a['Set_ID'] != $set) {
if ($set != 0) {
display_set($set, count($items));
foreach ($items as $i)
display_item($i)
}
$set = $a['Set_ID'];
$items = array();
}
$items[] = $a;
}
How about this:
$previous_set = false;
$items = '';
$item_count = 0;
foreach ($rows as $row)
{
if ($row['Set_ID'] != $previous_set)
{
if ($previous_set)
{
echo display_set($row['Set_ID'], $item_count);
echo $items;
}
$previous_class = $row['Set_ID'];
$item_count = 0;
$items = '';
}
$items .= display_item($row['Item_ID'], $row['Title']);
$item_count++;
}
echo display_set($row['Set_ID'], $item_count);
echo $items;