Undefined property within foreach unless print_r'd - php

I feel I must be missing something here. PHP displays: "Notice: Undefined property: DateTime::$date" when trying to display a property from an outer loop but if I print_r() the line before, then it prints the value with no error. Comment it out again, and the error comes back?
I suspect perhaps $iteration['EventTime']->date is getting confused with the date() function in PHP but am not sure how to overcome this via an escape. I cannot change the format of the object.
Object:
array (size=6)
'LINE' => string '2' (length=1)
'EventTime' =>
object(DateTime)[2]
public 'date' => string '2019-09-11 01:25:10.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/London' (length=13)
'Tag' => string 'PLC32.J.A.10.NOREAD' (length=19)
'Area' => string 'Material\PLC32' (length=14)
'Message' => string '32JA10 Consecutive No-read Fault' (length=32)
'FAULT_STATE' => int 1
Loop:
foreach ($sqlsrv_fetch_all as $index => $row) {
if ($row['FAULT_STATE'] == 1) {
foreach ($sqlsrv_fetch_all as $iteration) {
if ($iteration['LINE'] < $row['LINE'] || $iteration['Tag'] != $row['Tag'] || $iteration['FAULT_STATE'] == 1) {
continue;
} else {
//print_r($row);
echo "row: ".$row['EventTime']->date;
}
}
}
}
Should output "row: 2019-09-11 01:25:10.000000";
But unless I call print_r() first, it errors and outputs nothing.

This is actually a bug in PHP (I'm yet to find its ID in the bugtracker) that has been fixed with PHP 7.4 - see here.
print_r is one of a few ways to display internals of an object, including its private properties. Apparently, before PHP 7.4, calling print_r on an object caused its properties to become public (presumably using reflections, so that their contents could be displayed), but never turned back after that.
The documentation does not name \DateTime::$date as a public field. If you want to display date, use \DateTime::format() method instead.

Related

"Trying to get property of non-object" in SOAP PHP - not sure why this error is occuring

Hope you guys can help me... Still new at PHP and I am struggling to display parts of this Object/Array set of Results.
I am getting the following result $results back from a SOAP webservice:
`object(stdClass)[9]
public 'Summary' =>
object(stdClass)[2]
public 'ID' => string '1096408402' (length=10)
public 'IKey' => string '1440010962' (length=10)
public 'Address' =>
object(stdClass)[4]
public 'Forename' => string 'TEST' (length=4)
public 'Surname' => string 'TESTER' (length=6)
public 'DOB' => string '0000-00-00' (length=10)
public 'Telephone' => string 'Unavailable' (length=11)
public 'Occupants' =>
array (size=3)
0 =>
object(stdClass)[12]
...
1 =>
object(stdClass)[13]
...
2 =>
object(stdClass)[14]
...
3 =>
object(stdClass)[15]
...
Now I am attempting to put the data into a table format.
I have been successful in creating the table using a foreach on the section marked Occupants. I do this by calling Occupants as follows:
$occupants = ($results->Address->Occupants); and the data is extracted and populated into my table using my code (not relevent for this question).
My problem now is that when I try and do the same for Summary or Address it doesnt work: I get the error "Trying to get property of non-object"
I have tried $summary = $results->Summary and $summary = $results['Summary'] and neither works.
What I then want to do is run
<?php $summary = ($results->Summary);foreach($summary as $person):?>
and then I insert it into my table as follows:
<td><?=$person->ID?></td>
So any idea why I get this error? I dont think it is in the foreach aspect...?
Normally, you should get the "Summary" object with:
$summary = $results->Summary
in this case $summary is an object with 2 properties: "ID" and "IKey".
If you iterate over $summary with foreach, the value of $person would have the value of $summary->ID in the first loop iteration and the value of $summary->IKey in the second loop iteration. Both $summary->ID and $summary->IKey are strings and therefore non-objects, so I think that is why you get the error.
I suppose that you want do do this:
$summary = $results->Summary;
foreach ($summary as $value)
echo "<td>$value</td>";
This should output (for the given example):
<td>1096408402</td><td>1440010962</td>
For more information about Object Iteration, I recommend: http://php.net/manual/en/language.oop5.iterations.php

PHP Get variable value out of Object

I got following invalid code: (e.g. $column->Field == 'email')
echo $row[$column->Field];
With the Error:
Fatal error: Cannot use object of type stdClass as array
Thats the var_dump of $row:
object(stdClass)[17]
public 'id' => string '1' (length=1)
public 'email' => string 'master' (length=9)
public 'Name' => string 'THE MASTER' (length=28)
public 'reply' => string '1' (length=1)
I now what the error means i just can'T figure out how to work around it (i Might be too tired)
Im looking for something like that: What is the correct/working way to do so?
echo $row->$column->Field;
IDK how i didnt got to that earlier but i just defined a variable before hand
$field = $column->Field
echo $row->$field;
So 2 Solutios to this one:
1) Define a Variable:
$field = $column->Field;
echo $row->$field;
2) Credit to Abdo Adel:
If you want to do it in one line, try
$row->{$column->Field}

Is_Array Issue In Codeigniter Form Validation Callback Function

I've the following callback function in my codeiginter form validation rule:
function validate_milestone($mileStones, $csrf) {
if(is_array($mileStones)) {
foreach ($mileStones as $value) {
}
}
}
This is the result of var_dump
array (size=3)
0 =>
array (size=3)
'Name' => string 'a' (length=1)
'Amount' => string '50.00' (length=5)
'Type' => string 'AMOUNT' (length=6)
1 =>
array (size=3)
'Name' => string 'b' (length=1)
'Amount' => string '20.00' (length=5)
'Type' => string 'AMOUNT' (length=6)
2 =>
array (size=3)
'Name' => string 'c' (length=1)
'Amount' => string '30.00' (length=5)
'Type' => string 'AMOUNT' (length=6)
If I remove if(is_array()) condition from the above code, then PHP returns a warning of "Invalid argument supplied for foreach". When I used var_dump($mileStones) it gave array type of variable. Then what is the role of this PHP condition in removing the warning?
When you put the is_array() condition, the code block is simply skipped when $mileStones is not an array (which happens in some cases caused by some other portion of your code that you haven't shared here) and as a result the foreach statement is never executed and gets skipped (thus no warning):
if(is_array($mileStones)) {
echo 'This entire block is skipped when $mileStones is not an array.';
foreach ($mileStones as $value) {
}
}
Now when you remove the is_array() check, the foreach loop is executed no matter what and as $mileStones is not an array or is an empty array in some cases, the built-in warning is thrown. Try this to confirm:
if (is_array($mileStones)) {
foreach ($mileStones as $value) {
}
} else {
echo 'Damn, $mileStones is indeed not an array in some weird cases that I need to check now.';
}
Note: In my opinion you should not use the is_array() check as it simply ignores the situation and all the built-in error handling gets skipped - making debugging difficult.

How to get an object property->property from a stdClass with a string representing it

My situation is quite simple, but i'm still looking for a nice and short solution for it.
Here is my case:
I receive a soap response object which is my be different from a call to another.
Sometimes, these properties are objects themselves and may have properties we have to get. For this, an array is set for each type of call to select the data wanted and discard the rest.
By example, in a call we receive an object like this:
(I made a code easy to test by mocking the received object)
$objTest = new stdClass();
$objTest->Content1 = "";
$objTest->Content2 = new stdClass();
$objTest->Content2->prop1=1;
$objTest->Content2->prop2=2;
$objTest->Content2->prop3=3;
$objTest->Content3 = 3;
$objTest->Content4 = array('itm1'=>1, 'itm2'=>'two');
i want to check if $objTest->Content2->prop3 exist, but i don't know at the right moment i am looking for this because what i'm looking for is in the associative array.
The array for the call look like:
$map = array('Content3','Content2->prop3');
From now i am able to get the content of the Content3 property by doing this:
foreach ($map as $name => $value) {
if (isset($object->$name)) {
echo "$value: ". json_encode($object->$name)."\n";
}
}
But not for the other because of the reference "->".
Now my question:
Is there a way to get an unknown property of an unknown object as displayed above?
This is a result of the previous test:
Dump of objTests:
object(stdClass)[1]
public 'Content1' => string '' (length=0)
public 'Content2' => object(stdClass)[2]
public 'prop1' => int 1
public 'prop2' => int 2
public 'prop3' => int 3
public 'Content3' => int 3
public 'Content4' => array (size=2)
'itm1' => int 1
'itm2' => string 'two' (length=3)
Trying to access the proprerty prop3 of the content2 of the object with a string:
Standard way to get the value : $objTest->Content2->prop3
Result : 3
Test string: "Content3"
Result: 3
Test astring: "Content2->prop3"
( ! ) Notice: Undefined property: stdClass::$Content2->prop3
Hope i put everything to help understand my situation!
Thanks!
I don't know of a built-in PHP function that does this, but a function could be used to break up the string of properties and iterate through them to find the value of the last one in the string.
function get_property($object, $prop_string, $delimiter = '->') {
$prop_array = explode($delimiter, $prop_string);
foreach ($prop_array as $property) {
if (isset($object->{$property}))
$object = $object->{$property};
else
return;
}
return $object;
}

how to parse the json array elements using for loop to get the values one by one

i have a json array wherer i would like to pasre the json till the last element by using for loop for that i would like to get the number of array elements in the json array ,i have more than 3 objects in anarray ,so i am confused how to parse the json till the last element,
i can say you the idea
Count($json);
echo count;
for(i=0;i<l=count($json);i++)
{
then print the value of each key
}
i am stuck ,because there is no fixed lenght for the json i am getting as it is a server response it may return one object one may be twice or thrice or many ,so i thought it would be better to do with for loop ,as a json contain more than one json with 3 keys ,such as country can have more than one state,and one state can have more than one district ,plaese help me,i am stuck with question for last 2 days
thank you
An idea :
function printJson($json) {
foreach($json as $index=>$value) {
if(is_array($value)) {
printJson($value);
} else {
echo 'Value :'.$value.'<br />';
}
}
}
$stringJson = "{'location':[{...}]}"; //for example
printJson(json_decode($stringJson));
You can alternatively decode the json tring using json_decode() which will give u a php variable which u can then easily iterate over using php.
eg.
$string = '{"image":"fox.png","puzzlepieces":{"f":{"puzzlepiece":"one","position":"top:121px;left:389px;"},"x":{"puzzlepiece":"three","position":"top:164px;left:455px;"},"o":{"puzzlepiece":"two","position":"top:52px;left:435px;"}}}';
var_dump(json_decode($string));
will output as
object(stdClass)[1]
public 'image' => string 'fox.png' (length=7)
public 'puzzlepieces' =>
object(stdClass)[2]
public 'f' =>
object(stdClass)[3]
public 'puzzlepiece' => string 'one' (length=3)
public 'position' => string 'top:121px;left:389px;' (length=21)
public 'x' =>
object(stdClass)[4]
public 'puzzlepiece' => string 'three' (length=5)
public 'position' => string 'top:164px;left:455px;' (length=21)
public 'o' =>
object(stdClass)[5]
public 'puzzlepiece' => string 'two' (length=3)
public 'position' => string 'top:52px;left:435px;' (length=20)
My xdebug extension is on in WAMP so your var_dump might be a little differently formatted but overall you'd get a php variable from the array which u can iterate using foreach or other loops.
Read more on json_decode here

Categories