Illegal string offset when using string to reference array - php

I have classes, each with a date related member variable that always has the same naming format - field_{$node->type}_date
For example, if I my node type was 'car', the date field would be named field_car_date
So I am looping over all my nodes and I want to access the date related field for each of them. However I am getting an error. Here's the code
$date_field_key = 'field_' . $node->type . '_date';
if (isset($node->$date_field_key['und'][0]['value'])) {
I get an error because of the second line. The error is - Illegal string offset 'und'
The date related variable is an array and it does have an element with the key 'und'. If I write out the line explicitly - $node->field_car_date['und'][0]['value'] - it works fine. It's just when I dynamically create the field name that I get this problem.
Any solution for this, is my syntax incorrect?

You need to surround you key value in {} because it's a dynamically-assigned variable.
In your second line, you have $node->$date_field_key['und'][0]['value'] where you should have:
$node->{$date_field_key}['und'][0]['value']
Notice the {} surrounding the date_field_key
Good luck!

There is no reason to spare the variable:
$array = $this->$date_field_key;
$value = $array['und'][0]['value'];
If you get it to work, we then can discuss more advanced topics.

Related

Unable to get dynamic PHP's Object value using PHP variable

PHP is unable to get the value for dynamic object prepared as:
$abc->{$dynamic_object_pattern}
Where the value of the variable $dynamic_object_pattern is, json->{'data_1'}->{'value'}
For me, PHP 7.1 is understanding the statically defined pattern like below, and fetching the value as it should:
$abc->json->{'data_1'}->{'value'}
But not when I put the whole portion into a variable and then try to get its value. I Tried,
$abc->{$dynamic_object_pattern} and $abc->$dynamic_object_pattern
both ways, but no solution yet.
The error comes is Notice: Undefined property: stdClass::$json->{'data_1'}->{'value'}
I'm attempting an answer without seeing your JSON data
Here you say :
But not when I put the whole portion into a variable and then try to
get its value
From that line alone it sounds like you are trying to get value from a string rather than array. If you put the whole portion into a variable, PHP will interpret it as string. Make sure you add array() before newly created variable.
Natural array :
$array = array();
Now a string
$variable = $array;
Convert string to array
$new_array = array($variable);
Also, have you tried decoding?
// decode
$response = json_decode($new_array, true);
//print out
var_export(array_unique(array($response)));

How do I search and replace a string that occurs multiple times throughout an object, in both values and keys?

I want to replace all instances of a particular string in an object which includes properties, values and keys that include this string, including within longer keys/values that contain this string amongst other information.
Currently I'm doing this:
$amended_object = str_replace('search', 'replace', serialize($object));
$object = unserialize($amended_object);
So I turn the object into a string, search and replace, and convert it back.
However I often get Notice: unserialize(): Error at offset when the object is in a particular state, and it seems like it's not a very good solution.
When you serialize you get something like s:5:"value" which means string:length 5:"value". So if you change value to bob it is no longer length 5 and unserialize will error.
So you would need to correct the string lengths as well. Try JSON as it doesn't store the types or lengths:
$amended_object = str_replace('search', 'replace', json_encode($object));
$object = json_decode($amended_object);
Serialize wont work unless you correct the length of the containing string in the entity.
So you take the substring of the entity, split it up by the : sign, count/get the length of the total value string you want to correct and recalculate that with your replacement considered. Then update the stringcontent.

PHP - Function name from variable

Okay, I've found a possible solution for this, but for some reason, I can't make it work in my application. Apparently, if I have a variable which contains a name function, I could use
<?php echo $variable(); ?>
to output the function with the same name.
I'm using Codeigniter. It has a function in its Form helper to output a text field, which is
<?php form_input(); ?>
I have a variable
<?php $instance['taxon_field'] = 'form_input'; ?>
If I echo out this variable, I do get the needed value, 'form_input'. However, as soon as I try to echo
$instance['taxon_field']()
I get a warning:
Message: Illegal string offset 'taxon_field'
and a fatal error:
Call to undefined function p()
I am really clueless here, because echoing only the variable gives 'form_input', but echoing $variable() only gives 'p'.
Where am I doing wrong?
The actual problem here is that $instance is not an array, but a string. Judging from the error message, it's a string whose value starts with p.
The syntax $var[$key] is used not only to access array elements but also to index into strings, where $var[0] would be the first character (actually, byte) of $var etc. If $instance is a string and you write $instance['taxon_field'] then PHP will try to convert 'taxon_field' to an integer in order to index into the string. This results in 0 as per the usual conversion rules, so the whole expression gets you the first letter of the string.
Assuming that the string starts with p it's then pretty obvious why it tries to call a function with that name.
Use call_user_func()
call_user_func($instance['taxon_field']);
The confusion created is actually my own fault because I failed to provide some aditional information which I thought was not important, but turned out to be crutial. My $instance[] array is actually a result of a foreach loop (two of them, to be precise) and is a part of a bigger multidimensional array. The actual code is more complicated, but I'll try to represent it right:
<?php
$bigger_array = array(
0 => array(
'field_one' => 'value_one',
'field_two' => 'value_two',
'field_three' => 'new_function'
),
1 => array(
'field_one' => 'new_value_one',
'field_two' => 'new_value_two',
'field_three' => 'echo'
)
);
function new_function()
{
echo 'New function called.';
}
foreach($bigger_array as $instance)
{
$name = $instance['field_three'];
$name('Hello World!');
}
?>
This will output the following:
New function called.
Fatal error: Call to undefined function echo() in /opt/lampp/htdocs/bla.php on line 69
In other words, the newly defined function works fine, but the built-in 'echo' doesn't.
This is actually not my original problem, this is something that I've encountered while trying to debug the initial issue. And the original problem is that creating a function from a single-dimensional array works okay. whereas creating a function from a multi-dimensional array within a foreach loop transforms the array into a string with the value of its last member.
Now, I'm still not really able to fully answer my question, but I think information I'm giving could lead to a solution. In the simplified example that I gave here, why am I getting the message that echo() function is not defined, while the new function works fine?

php appending string to stdClass object

I'm pulling records from database, and I have a filed called content_fr
the _fr is being dynamicaly created based on a site language.
Getting all records from the table gives me of course content_fr field. What I need to do is manually assign the suffix in this case _fr if I try to concatenate $row->content.'_fr' I get the error Notice: Undefined property: stdClass::$content, which makes sense since $content does not exist, but $content_fr does. Using standard arrays I was able to do it like $row['content_fr'], and worked fine, but now using stdClass I'm getting an error.
How can I convert $row->content.'_fr' into one string, so that php sees it as $row->content_fr ?
Try it like this :
$row -> {'content_' . $language}; // assuming $language = 'fr'
You can do it as follows:
$row->{'content_fr'};
EDIT: By the way, this question has been asked here many times. See previous threads such as this one: Accessing object's properties like if the objects were arrays.
Try something like this:
$lang = 'fr';
$property = 'content_' . $lang; // content_fr
$row->$property = 'something';

php and sql together in the func of a class

this piece of code was given in a book.
$query="select name, description from widget where widgetid=$widgetid";
$rs=mysql_query($query,$this->connect);
if(!is_resource($rs))
throw new exception("could not execute the query");
if(!mysql_num_rows($rs))
throw new exception("found no rows");
$data=mysql_fetch_array($rs);
$this->name=data['name'];
$this->description['description'];
what is meant by the last two lines of the code?
The third line before the end :
$data=mysql_fetch_array($rs);
will fetch one row of the resultset that corresponds to the SQL query, and assign it, as an array, to $data.
See the documentation of mysql_fetch_array() for more details.
The next line :
$this->name=data['name'];
is not valid PHP, and will result in a Parse Error.
Instead, to be valid, it should be written like this :
$this->name=$data['name'];
Note the additionnal $, that means that $data is a variable.
It will assign the value of the name item of the $data array to the name attribute of the current object.
Basically : the name attribute of the current instance of your class will contain the value of the name column of the row you've fetched from database.
And, finally, the last line :
$this->description['description'];
doesn't do anything : you access the description item of the attribute description of the current object -- that attribute being an array ; but you don't do anything with it.
I suppose it should be written :
$this->description = $data['description'];
In which case it would do the same kind of thing as the previous line -- with the description item/field/attribute.
Considering your question, you should take a look at the PHP manual, and, especially, at the following sections :
Arrays
Objects
Classes and objects
$this refers to the current instance of the class.
-> tells PHP to refer to a member of the instance.
name is the referred member.
So, the following line:
$this->name = $data['name'];
Sets the property name of the current instance ($this) to whatever value held by the array $data at index name.
For more information, you can read the OOP Basics in the PHP Documentation:
PHP Documentation: Classes and Objects - The Basics
PHP Documentation: Classes and Objects - Properties
Well for starters, "data" is the array that hold the results of your query.
In your query you are retrieving "name" and "description" from the table "widget".
$this->name = data['name'] is assigning the value of name from the query to the name property or variable in your instance. $this refers to the current instance
Does that help?
Considering this code is from book, I think it is part of some method where widget name and description is fetched from DB and updated on class properties.
BTW, if last two lines are as is as you pasted then there is some print mistake :)

Categories