PHP doesn't find array elements - php

A library I use uses an array. Applying print_r to that array prints this:
Array
(
[*queueId] => 1
[*handle] => 9b875867b36d568483fb35fdb8b0bbf6
[*body] => First string in the TestQueue
[*md5] => c23ba714199666efbc1dcd5659bb0a0a
[*timeout] => 1408003330.6534
[*id] => 2
[*creationdate] => 2014-08-13 16:03:37
)
The library uses a magic getter on that array
public function __get($key)
{
if (!array_key_exists($key, $this->_data)) {
throw new Exception\InvalidArgumentException("Specified field \"$key\" is not in the message");
}
return $this->_data[$key];
}
When I try to access
$myObject->body
I run into the exception. In fact, the debugger shows that array_key_exists will return false while the _data array is available as printed above

The asterisk indicates that this array is a representation of an object, probably the original object property is protected.
http://php.net/manual/en/language.types.array.php#language.types.array.casting

As I explained in the comments, the array keys actually start with an asterisk. Since you can't call them using the regular syntax of $obj->*body (it'll cause a syntax error), you can use the following:
$myObject->{'*body'}
This should solve your problem.

Assuming that $myObject is the array you are talking from:
You can't access arrays with ->, use $myObject['*body'] instead. (And you should as well change the name to $myArray, for example)

As #MarkBaker stated in the comment of my question, the problem was that I was serializing an object with private properties to the array. The asterisk were marks that these properties were private.

Related

Retrieving PHP property name as string

I have some JSON, if I var_dump the output looks like:
var_dump( $oJSON->{$oQ->sQuestionName} );
object(stdClass)[14]
public 'Lease' => boolean true
I would like to retrieve 'Lease' as a string.
I've tried casting it:
(string)$oJSON->{$oQ->sQuestionName}
but it returns an E_RECOVERABLE:
E_RECOVERABLE_ERROR Error: Object of class stdClass could not be converted to string
The following works, however I feel there must be a better way?
array_shift(array_values(array_keys(get_object_vars($oJSON->{$oQ->sQuestionName}))));
N.B. I can't use to use the following due to compatability issues
array_keys(get_object_vars($oJSON->{$oQ->sQuestionName}))[0]
Use ReflectionClass::getProperties() to get a list of the object's properties.
$reflect = new ReflectionClass($foo);
$props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);
You can convert your desired object to an array first
$array = (array) $oJSON->{$oQ->sQuestionName};
Then you can take its first element's key
echo key($array); // Should say Lease
Fiddle
You can use json_decode with second parameter true
For example:
$str = '{"0":{"id":"123","name":"Title"}}';
var_dump(json_decode($str,true));
So, you will have an array with string objects.

How to write a bann function in php?

I have an array of many banned string and i have a small string contains one keywords, too and i want to write a function in php like this:
function is_ban($keyword,$bannedList) {
}
where $keyword is small string and $bannedList is an array like
Array
(
[0] => php
[1] => html
[2] => java
[3] => css
[....]
)
The function check keyword in banned list and return true or false.
function is_ban($keyword,$bannedList) {
return in_array($keyword, $bannedList);
}
This is my first reply on a php related question. As others have said, if you have a precisely defined array of banned words, and you have already taken the time to get the word $keyword from the user, then by all means just use PHP's native function in_array(). You may however need to do the following:
if(in_array(strtolower($keyword), $bannedList)){ //return true }
Just make sure of course that your $bannedList array is all lowercase as well. If however you need to do pattern matches inside longer strings, then you'll need to resort to regular expressions.
This is a simple way to define your function
function is_ban($keyword,$bannedList)
{
return in_array($keyword, $bannedList);
}

Unexpected result when comparing PHP objects

When I compared two different objects, it returns firstly true, and than after print_r (on objects) returned false.
From PHP manual:
Two object instances are equal if they have the same attributes and values, and are instances of the same class.
But here, in example, I set different values. Why the result is different between PHP 5.4.0 - 5.5.7?
abstract class first
{
protected $someArray = array();
}
class second extends first
{
protected $someArray = array();
protected $someValue = null;
public function __construct($someValue)
{
$this->someValue = $someValue;
}
}
$objFirst = new second('123');
$objSecond = new second('321');
var_dump ($objFirst == $objSecond);
print_r($objFirst);
var_dump ($objFirst == $objSecond);
Result is:
bool(true)
second Object ( [someArray:protected] =>
Array ( ) [someValue:protected] => 123 )
bool(false)
But what I expected was:
bool(false)
second Object ( [someArray:protected] =>
Array ( ) [someValue:protected] => 123 )
bool(false)
This was a bug in PHP. It's fixed now, see the commit. In short:
If you extend a class and redefine the same property the properties_table of the object ends up having a NULL value.
The comparison code incorrectly aborted comparison when two objects had a NULL value in the properties_table at the same index - reporting the objects as equal. That doesn't make sense of course, because it discards all differences in the following properties. This is fixed now.
The reason why print_r changes the result, is that by fetching the properties of the object (get_properties) the properties hashtable is rebuilt (rebuild_properties_table) which uses entirely different (and correct) comparison code.
For context, properties_table and properties are two different ways PHP uses to represent properties - the former being way more efficient and used for declared properties and the latter used for dynamic properties. The print_r call effectively makes the object properties dynamic.
Well, ok, Identified as bug in php https://bugs.php.net/bug.php?id=66286.
Also here: Unexpected result when comparing PHP objects

PHP JSON get the name of an object

<?
stdClass Object
(
[image_header] => Array
(
[0] => stdClass Object
(
[img] => /headers/header.jpg
)
)
)
?>
Object name image_header is variable, so it can be any string. Can I access this string without knowing what it is?
#Jon his answer was satisfying for me.
For others who want to use variable objectnames this way:
To acces this object with the variablename I had to use curly brackets:
$key = key(get_object_vars($_json));
$_json->{$key}[0]->img;
You can do it conveniently with get_object_vars:
$propertyName = key(get_object_vars($object));
If you don't know what the name of the property is, you can use PHP's Reflection classes, or more simply use get_object_vars().
get_object_vars() is probably what you're looking for here - it "Returns an associative array of defined object accessible non-static properties for the specified object in scope. If a property has not been assigned a value, it will be returned with a NULL value." So, you get the property names and their values returned in an associative array.
Alternatively, you could use some of PHP's reflection magic, although it might be a bit overkill here, depending on your end goal. The reflection classes are very powerful, and may be worth using if you have more complex requirements for what you're trying to achieve. As an example:
// let's say $obj is the object you provided in your question
// Instantiate the reflection object
$reflector = new ReflectionClass($obj);
// Get properties of $obj, returned as an array of ReflectionProperty objects
$properties = $reflector->getProperties();
foreach ( $properties as $property ) {
echo $property->getName(); // In your example, this would echo 'image_header'
}
There are a couple of possibilities. If you're using json_decode() you can pass true in as the second parameter to parse the data as an associative array.
$data = json_decode($myJson, true);
print_r( $data['image_header'] );
You can also access an object property from a variable like this.
$myProperty = 'image_header';
print_r( $data->$myProperty );
If by "you don't know what it is" you mean you don't know the key at all you can use my first example and use array_values() to get the values by index.
$values = array_values($data);
// image_header
print_r( $values[0] );

Dynamically discover/process PHP object

Is it possible to dynamically discover the properties of a PHP object? I have an object I want to strip and return it as a fully filled stdClass object, therefore I need to get rid of some sublevel - internal - objecttypes used in the input.
My guess is I need it to be recursive, since properties of objects in the source-object can contain objects, and so on.
Any suggestions, I'm kinda stuck? I've tried fiddling with the reflection-class, get_object_vars and casting the object to an array. All without any success to be honest..
tested and this seems to work:
<?php
class myobj {private $privatevar = 'private'; public $hello = 'hellooo';}
$obj = (object)array('one' => 1, 'two' => (object)array('sub' => (object)(array('three' => 3, 'obj' => new myobj))));
var_dump($obj);
echo "\n", json_encode($obj), "\n";
$recursive_public_vars = json_decode(json_encode($obj));
var_dump($recursive_public_vars);
You can walk through an object's (public) properties using foreach:
foreach ($object as $property => $value)
... // do stuff
if you encounter another object in there (if (is_object($value))), you would have to repeat the same thing. Ideally, this would happen in a recursive function.

Categories