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 . . .
Related
From a JSON array I want to create a PHP code and write it to MySQL. How can I do this? Below is my JSON array:
{
"school1":[
{
"name":"aaa Universe",
"url":"http:\/\/aaa_Universe.com\/"
},
{
"name":"bbb Universe",
"url":"http:\/\/bbb_Universe.com\/"
}
],
....................................
....................................
"school4":[
{
"name":"ggg Universe",
"url":"http:\/\/ggg_Universe.com\/"
},
{
"name":"hhh Universe",
"url":"http:\/\/hhh_Universe.com\/"
}
]
}
I have written below PHP script to get expected result. Could you suggest other way:
$data = file_get_contents ("list.json");
$json = json_decode($data, true);
foreach ($json as $key => $value) {
if (!is_array($value)) {
echo $key . '=>' . $value . '<br/>';
} else {
foreach ($value as $key => $val) {
echo $key . '=>' . $val . '<br/>';
}
}
}
When you are generating a dynamic query, PHP Data Objects (PDO) is the method you should use in nearly every case. PDO prevents escape characters from being a security threat or causing bugs. Here is a link.
That said, in your particular case, I take it that you only need a quick script to generate a query. I am assuming the "school1", "school2".... are the foreign keys of the table. I'll use the function addslashes to prevent errors on the escape characters instead of the PDO.
$data = file_get_contents ("list.json");
$json = json_decode($data, true);
$statement = "";
foreach ($json as $school => $schools) {
if (count($schools) > 0) {
foreach($schools as $i => $schoolInfo){
if($statement == ""){
$statement .= "INSERT INTO dataBase.table (school,name,url) VALUES";
$statement .= " ('".addslashes($school)."', '".addslashes($schoolInfo['name'])."','" . addslashes($schoolInfo['url']) ."' )";
}else{
$statement .= ", ('".addslashes($school)."', '".addslashes($schoolInfo['name'])."','" . addslashes($schoolInfo['url']) ."' )";
}
}
}
}
echo $statement;
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";
I'm trying to capture a user's checkbox selection from a dynamically generated list of options but I'm getting "Array" instead of the names selected.
In my last test, I checked 2 of the three boxes and got 3 instances of "Array" back.
This is my query that finds the names:
$query = "SELECT id, first_name, last_name
FROM users WHERE location_id = " . $location_id;
$result = mysqli_query($connection, $query);
if (!$result)
{
die("Database query failed: " . mysqli_error($connection));
}
while ($row = mysqli_fetch_array($result))
{
$name = $row['first_name'] . " " . $row['last_name'];
echo '<label><input type="checkbox" name="emp_name[]" id="emp_name[]" value="' . $name . '"> ' . $name . '</label>';
}
I then post the array of names like this:
$attendee = $_POST['emp_name'];
And try to generate the list of names for my email like this:
$values = ('emp_name');
foreach ($values as $value) {
$$value = (array)$_POST[$value];
}
for($i = 0; $i < count($attendee); $i++){
$attendees = array();
foreach ($values as $value) {
$attendees[] = ${$value}[$i];
}
Can someone help me see what's wrong?
I changed my code and included a part of the html that I'm trying to render:
foreach ($attendee as $name) {
$attendees[] = $name;
$htmlBody .= "<tr><td>{$attendees}</td></tr>";
}
But it still returns Array.
Not sure why you do this:
$attendee = (array)$_POST['emp_name'];
Try to replace it with:
$attendee = $_POST['emp_name'];
From your question it's not too clear, but I think you're creating an array within an array,and that that's the issue.
If the above doesn't help, try to var_dump() the variable that gives you "Array" response, and you'll see what's within it.
EDIT: In addition to the change above, try to make this change too:
Replace all this code:
$values = ('emp_name');
foreach ($values as $value) {
$$value = (array)$_POST[$value];
}
for($i = 0; $i < count($attendee); $i++){
$attendees = array();
foreach ($values as $value) {
$attendees[] = ${$value}[$i];
}
with:
foreach ($_POST['emp_name'] as $name) {
$attendees[] = $name;
}
EDIT #2:
According to your code:
foreach ($attendee as $name) {
$attendees[] = $name;
$htmlBody .= "<tr><td>{$attendees}</td></tr>";
}
It's totally normal that you're getting Array instead of a name. See, by writing:
$attendees[] = $name;
you're implying to php that it's an array. On the other hand the foreach loop does the opposite thing, it takes each of the values from $attendee array and makes it available to you as $name variable. So you're basically doing the right thing, and then reverting it back to array for no reason.
SOLUTION:
Replace {$attendees} with {$name}. And it should work.
You can write that with alot less code.
$attendees will now contain your checked checkboxes.
$attendees = array()
foreach($_POST['emp_name'] as $name){
$attendees[] = $name;
}
I am querying my database for results (which all display correctly) and then while running a foreach statement I am attempting to look in another table for a matching ID to gather an override price which will take the place of the 'storeprice' listed in the first result.
Here is my model:
public function fetch_products($limit, $start, $manuid) {
$this->db->order_by('productname', 'ASC');
$this->db->limit($limit, $start);
$query = $this->db->get_where('products', array('manuid' => $manuid, 'active' => 1));
if($query->num_rows() > 0){
foreach($query->result() as $row){
$data[] = $row;
$pid = $row->id;
// Check for Price Override
$squery = $this->db->get_where('price_override', array('id' => $pid));
if($squery->num_rows() > 0){
$result = $squery->row();
$override = $result->storeprice;
$data['override'] = $override;
} else {
$override = 0;
$data['override'] = $override;
}
}
return $data;
}
return false;
}
The $data['override'] is what is causing me an error. The following error to be precise:
Message: Undefined property: stdClass::$override
In the controller I am using the following:
$data['results'] = $this->store_products_model->fetch_products($config["per_page"], $page, $manuid);
And finally in the view I am calling the results inside of a table to display. All will display except for the override:
foreach ($results as $product){
echo '<tr>';
echo '<td>' . $product->productname . '</td>';
if($product->override != 0){
echo '<td>$' . $product->override . '</td>';
} else {
echo '<td>$' . $product->storeprice . '</td>';
}
echo '<td>$' . $product->saleprice . '</td>';
echo '<td>' . $product->storepoints . '</td>';
echo '<td>Edit';
echo '</tr>';
}
Anyone see what I could be doing wrong here to give me the following error?
Message: Undefined property: stdClass::$override
The row is an object, not an array. Try:
$data->override = $override
edit:
Well, actually, $data is an array, but your inserting an object into it, so it would be
$last_index = sizeof($data) - 1;
$data[$last_index]->override = $override;
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;