PHP - warning - Undefined property: stdClass - fix? [duplicate] - php

This question already has answers here:
PHP check whether property exists in object or class
(10 answers)
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Duplicate This question has been answered, is not unique, and doesn’t differentiate itself from another question.
I get this warning in my error logs and wanted to know how to correct this issues in my code.
Warning:
PHP Notice: Undefined property: stdClass::$records in script.php on line 440
Some Code:
// Parse object to get account id's
// The response doesn't have the records attribute sometimes.
$role_arr = getRole($response->records); // Line 440
Response if records exists
stdClass Object
(
[done] => 1
[queryLocator] =>
[records] => Array
(
[0] => stdClass Object
(
[type] => User
[Id] =>
[any] => stdClass Object
(
[type] => My Role
[Id] =>
[any] => <sf:Name>My Name</sf:Name>
)
)
)
[size] => 1
)
Response if records does not exist
stdClass Object
(
[done] => 1
[queryLocator] =>
[size] => 0
)
I was thinking something like array_key_exists() functionality but for objects, anything? or am I going about this the wrong way?

if(isset($response->records))
print "we've got records!";

isset() is fine for top level, but empty() is much more useful to find whether nested values are set. Eg:
if(isset($json['foo'] && isset($json['foo']['bar'])) {
$value = $json['foo']['bar']
}
Or:
if (!empty($json['foo']['bar']) {
$value = $json['foo']['bar']
}

In this case, I would use:
if (!empty($response->records)) {
// do something
}
You won't get any ugly notices if the property doesn't exist, and you'll know you've actually got some records to work with, ie. $response->records is not an empty array, NULL, FALSE, or any other empty values.

You can use property_exists
http://www.php.net/manual/en/function.property-exists.php

If you want to use property_exists, you'll need to get the name of the class with get_class()
In this case it would be :
if( property_exists( get_class($response), 'records' ) ){
$role_arr = getRole($response->records);
}
else
{
...
}

Error control operator
In case the warning is expected you can use the error control operator # to suppress thrown messages.
$role_arr = getRole(#$response->records);
While this reduces clutter in your code you should use it with caution as it may make debugging future errors harder. An example where using # may be useful is when creating an object from user input and running it through a validation method before using it in further logic.
Null Coalesce Operator
Another alternative is using the isset_ternary operator ??. This allows you to avoid warnings and assign default value in a short one line fashion.
$role_arr = getRole($response->records ?? null);

The response itself seems to have the size of the records. You can use that to check if records exist. Something like:
if($response->size > 0){
$role_arr = getRole($response->records);
}

If think this will work:
if(sizeof($response->records)>0)
$role_arr = getRole($response->records);
newly defined proprties included too.

Related

If condition is throwing the notice

The if condition is throwing the following notice, how to fix this?
Notice: Trying to get property of non-object in /view_rep.php on line 17
Here is my php code
if ($check->check_area->id != #$_GET['check_area']) {
unset($check[$k]);
}
I tried the following but still, I can see multiple notices
error_reporting(0);
ini_set('display_errors',0);
Print_r($check), print thefollowing
[check_area] => stdClass Object
(
[id] => 5429140
[url] => /api/v2/checke_areas/5429140
[name] => Other
)
It seems $check is an array of object(s). If that's the case then change your if condition
if ($check->check_area->id ...
to
if ($check['check_area']->id ...
In order for $check->check_area->id to work:
$check must be an object with a property of check_area.
$check->check_area must be an object with a property of id.
One or both of these has not been met if you are getting a property of a non-object error.
Try checking whether they are objects before trying to access the property:
if ($check instanceof stdClass) {
}

Yii2 array of objects, find the one

I have an array in yii2, and ocassionally it's only 1 single object that is not empty (all other element of array is empty) and I don't know which one is it. How can I either find the one that is not empty, or (my idea what I was trying), to create a new array, with array_filter (but I'm not sure if it works also with array of objects), to have only the one object in it.
if (count($ttepk) == 1) {
$ttep_filtered[] = array_filter($ttepk);
$id = $ttep_filtered[0]->id;
}
But it was also not working. I get the error message: PHP Notice – yii\base\ErrorException Trying to get property of non-object.
Before array_filter it looks like this:
Array
(
[3] => app\models\Model Object
(
after array_filter:
Array
(
[0] => Array
(
[3] => app\models\Model Object
(
So it seems, array_filter is not the one I need, or I use it the wrong way.
Can you please help me? Thank you!
You can try something like this
$filtered = array_filter($ttepk, function($item) {
return $item instanceof app\models\Model;
});
if (count($filtered) == 1) {
$id = reset($filtered)->id;
}

in_array() expects parameter 2 to be array

I have this idea of an multiarray with my files sorted into different groups/arrays.
Thinking it would be the easiest and most clean way to check what file we're inside, and should the navigation state be set to active on navigation tab 1,2 or 3?
I have this array;
Array
(
[home] => Array
(
[0] => index.php
[1] => something.php
)
[tour] => Array
(
[0] => tour.php
)
[tutorials] => Array
(
[0] => tutorials.php
)
)
The idea is, if i click on the home navigation button it goes to the index.php and a function checks whether it's the Home button that needs the active state, or the Tour button. In this case its the Home button.
[home] => Array
(
[0] => index.php
I made this function
function findNavigationActive($tap, $filename) {
if(in_array($filename, $topNavigationPages[$tap])) {
return 1;
}
return 0;
}
it should check, if index.php ($filename) is in the Home ($tap) array or navi-tap, then return 1. Unfortunately i get this error insted;
Warning: in_array() expects parameter 2 to be array, null given in /project/../../topNavigationHandler.php on line 21
What am I doing wrong?
FIXED
Used global $topNavigationPages; outside the function, and set $topNavigationPages values (array) beneath, and again used global $topNavigationPages inside the function to pull the array inside.
Thanks #tombs !
What this error means is that the second parameter isn't an array, therefore you can try something like this.:
if (is_array($topNavigationPages[$tap])) {
if(in_array($filename, $topNavigationPages[$tap])) {
return 1;
}
}
return 0;
You can do this without nesting the if loops by using a strict and operator.
Hope this helps
Note:
To resolve your scope issue you can use either a global value or a constant. To use a constant use the 'define' function, for a global declare the variable as such at the beginning of your file and in every subsequent function that you use it in. I strongly recommend using a constant.

how can I read object values and atributes with php?

Ive been working with some code and I am recieving a var (I didnt work the entire code, so, I dont know how it was made), my problem is that I get something like this
AdminUserRoleDecorator Object (
[user:AdminUserRoleDecorator:private] => EssUserRoleDecorator Object (
[user:EssUserRoleDecorator:private] => User Object (
[topMenuItemsArray:User:private] => Array ( )
[employeeList:User:private] => Array ( )
[activeProjectList:User:private] => Array ( )
[empNumber:User:private] => [allowedActions:User:private] => Array ( )
[nextState:User:private] => [userId:User:private] => 1
[userTimeZoneOffset:User:private] => -6
To be honest, and It could sound like a very stupid question, I dont know how to read that, normally I get the atributes in the way $myobject->atribute , now this I really have no idea, any way I can access to this? for example, I want to get the userId, I see its there, with :user:private (which I also dont know what are they for).
If I try
$myobject->User;
for example, I get nothing back.
Thanks.
EDIT:
I tried $myobject->user
and I am getting this
Fatal error: Cannot access private property AdminUserRoleDecorator
I am working with symfony by the way.
From the answer I gave here, you can get some insight into objects with get_class_methods() (php reference) and get_class_vars(). On that post, I made up a function to help me learn more about class methods available:
show_methods($playlistListFeed);
function show_methods( $_a ) {
echo "<h3>Methods for ".get_class($_a)."</h3>";
$_a= get_class_methods($_a);
$_a=array_unique($_a);
array_multisort(&$_a);
$i=0;
foreach( $_a as $method ) {
$i++;
printf("%-30.30s",$method);
if($i%5==0)
echo "\n";
}
}

Setting the key of an object property that is an array

Just today I noticed a strange behavior in an object model that was previously working just fine (I have checked everything possible and nothing about its configuration has changed, so I am suspecting a change to PHP version and wondering if anyone else has experience anything similar)
Until recently, I could set the keys of object properties that were arrays manually. The specific implememation of this in one of my models was contained in a gallery class that looked like this:
public function __construct($gid){
parent::__construct($gid);
$this->Photos = $this->getPhotos();
$this->AlbumCover = $this->getCover();
}
public function getPhotos(){
$sql = 'SELECT GalleryPhotoID FROM GalleryPhoto WHERE GalleryID = ?';
$params = array($this->GalleryID);
$allids = DatabaseHandler::GetAll($sql, $params);
$output = array();
foreach($allids as $id){
$gp = new GalleryPhoto($id['GalleryPhotoID']);
$output[$gp->GalleryPhotoID] = $gp;
}
return $output;
}
Irrelevant parts omitted.
Basically, I could set the array keys of the Gallery's Photos object to the individual photo's id in the database. This just made it easier to code for individual iteration and made the whole thing run smoother.
Now, no matter what I set that key to, automatic integers are generated when the foreach runs. I even tried typing a literal string in there, which theoretically should replace every iteration, but I still got incremented, automatic integers for the keys of the property Photos.
[Photos] => Array
(
[0] => GalleryPhoto Object
(
[GalleryID] => 9
[Caption] =>
[Orientation] => 0
[AlbumCover] =>
[DateAdded] => 2011-01-03 16:58:51
[GalleryPhotoID] => 63
[Thumbnail] =>
[Image] =>
[src] => http://..com/galleryImage/getImage/63
)
[1] => GalleryPhoto Object
(
[GalleryID] => 9
[Caption] =>
[Orientation] => 0
[AlbumCover] =>
[DateAdded] => 2011-01-03 16:58:51
[GalleryPhotoID] => 64
[Thumbnail] =>
[Image] =>
[src] => http://..com/galleryImage/getImage/64
)
)
Has the abillity to manually set keys within an object property that is an array been removed in some minor release and I am unaware of it? I have googled all over, looked through the PHP manual site and found no answer. Has anyone experienced anything similar? Is there a better approach I should consider? I only really went with this because it made it so much easier to implement a next/previous system via ajax requests back to the next logical id (keeping in mind that ids can be deleted between!)
Thanks!
I don't see anything wrong with what you have, and I've never experienced the behavior you describe. However, a quick solution could be to replace the assignment line with something like this:
$output[$id['GalleryPhotoID']] = $gp;
You could also echo $gp->GalleryPhotoID; to ensure that the GalleryPhotoID property can actually be accessed that way.
Lastly, you said you replaced the above line with something akin to:
$output['foobar'] = $gp;
and it still created a new entry, with integer keys, for each entry? If that's the case, then I think there may be something in the code you omitted that's causing the problem.
Facepalm all the way. The effluvium of New Year's must still be in my brain, else I would have noticed that the function I added to fetch the album cover thumbnail shuffled the array if there wasn't a photo with the AlbumCover property set!
private function getCover(){
foreach($this->Photos as $ind=>$p){
if($p->AlbumCover){
return $this->Photos[$ind];
}
}
shuffle($this->Photos); //this is the problem
return current($this->Photos);
}
I amended this to just make a local copy of the variable and shuffle that instead if no cover is set.
private function getCover(){
foreach($this->Photos as $ind=>$p){
if($p->AlbumCover){
return $this->Photos[$ind];
}
}
$Photos = $this->Photos;
shuffle($Photos);
return current($Photos);
}
I accepted and upvoted both the answer and the comment posted since your caveats lead me to my error. Thanks guys!

Categories