Accessing PHP object properties when property name has non allowed chars [duplicate] - php

This question already has answers here:
Access object property with disallowed character in property name
(2 answers)
Closed 4 months ago.
I need to access a php object property which I specify as variable.
$phpObj->$property
This $property might contain chars like dash(-), quotes, percent, even whitespace ect. PHP does not allow these chars to be used as variable names, resulting which I am unable to access these properties.
What would be a good solution to handle this? I'm open with encoding the $property to something alphanumeric first and then using it as property variable but this encoding should be unique for a particular string.
Eg, I want to make sure that $phpObj->First-Prop and $phpObj->first-prop should be identified differently.

$propertyName = 'property-name';
$phpObj->{$propertyName} = ...
$phpObj->{"property-name"} = ...
only this may be problem:
$phpObj->First-Prop and $phpObj->first-prop
variable/function/method/property definitions in php are not case-sensitive...

not sure what you wish to achieve here but.
But
you would be best to impliment a whitelist of useable chars, a-zA-Z0-9 im guessing possible _. then you can assign the property knowing that all of the letters are allowed in php.
i dont understand why the properties need unique property names, surely a property of key with a unique value would achieve a similiar thing, could be appended to everything.
php is not case sensetive so $phpObj->First-Prop and $phpObj->First-Prop will take the last property.
i hope that helps, if you have any more on the implimentation and more importantly what you are trying to achieve i'll do my best to help

Related

How can i use :: as a character within my variable in PHP

So this might be a simple question but not one I can find an answer for I have a variable that looks at a standard class object and stores the value from the various field names. Unfortunately, one of my fields is called [JOB::c_job_id]. If I use this in my variable
$jobid = ($json_data_single->response->data[0]->fieldData->JOB::c_job_id);
then it thinks the:: is a Scope Resolution Operator(::) but I just want to retrieve the data from the field, how can I do this?
Any help will be greatly appreciated.
If there is no way for you to rename that very unfortunately named key in the JSON, you can take one of the following approaches:
$json = '{"JOB::c_job_id": 453}';
$decodedAsObject = json_decode($json);
var_dump($decodedAsObject->{'JOB::c_job_id'});
$decodedAsArray = json_decode($json, true);
var_dump($decodedAsArray['JOB::c_job_id']);
The first one requires you to encase the property name in {} to make it be interpreted literally. The other is a bit more straightforward, because when you decode as an array, array keys are simple strings and there is no trouble when they contain characters or character sequences that can otherwise be interpreted as having special meaning for execution.
Live test available here.

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.

How do I push an element onto an array who's name is contained in a variable?

I'm making a generic php class which autoloads values into an object from a Database
To set properties I use this:
$object->$propertyName = $valueFromDB; where the value of propertyName is comes from the mysql field name..
Now I want to push something onto an array in a similar fashion:
This works..
$object->$arryName = array();
But this doesn't..
$object->$arryName[] = "test";
How can I work around this?
$object->{$arryName}[] = "test"
The curly braces change the order of operations and will make PHP evaluate the variable name before the hard braces.
If you want to do a associative array, this gets a little more complicated:
$object->{$arryName}[$keyname] = "test"
In this case, you can put curly braces around $keyname but it's entirely optional.
On a related note.. variable variables are usually - but not always - a sign of something screwy. They're also a pain to whoever is coming after you who has to debug, refactor, do any grepping, etc. If you must use them, fine but make sure you've considered the ramifications.

How to access object property when property name contains - (hyphen) [duplicate]

This question already has answers here:
How do I access this object property with an illegal name?
(2 answers)
Closed 10 months ago.
I need an escape sequence for - or the minus sign for php. The object has a name-value pair where the name happens to be having - between 2 words.
I can't do this using \ the standard escape sequence (- isn't anyways documented).
I can store the name in a $myvariable which can be used but out of curiosity is it possible to do the following?
$myobject->myweird-name
This gives an Error because of -
This is what you need:
$myobject->{'myweird-name'};
If you need to look up an index, there are a couple of ways of doing it:
// use a variable
$prop = 'my-crazy-property';
$obj->$prop;
// use {}
$obj->{'my-crazy-property'};
// get_object_vars (better with a lot of crazy properties)
$vars = get_object_vars($obj);
$vars['my-crazy-property'];
// you can cast to an array directly
$arr = (array)$obj;
$arr['my-crazy-property'];
If you need to work within a string (which is not your best idea, you should be using manual concatenation where possible as it is faster and parsed strings is unnecessary), then you should use {} to basically escape the entire sequence:
$foo = new stdClass();
$foo->{"my-crazy-property"} = 1;
var_dump("my crazy property is {$foo->{"my-crazy-property"}}";
Since you mentioned that this is LinkedIn's API which, I believe, has the option of returning XML, it might be faster (and possibly cleaner/clearer) to use the XML method calls and not use the objects themselves. Food for thought.

PHP - Exploding on character(s) that can NEVER be user-defined... How?

Ok, am trying to find a character or group of characters, or something that can be used that I can explode from, since the text is user-defined, I need to be able to explode from a value that I have that can never be within the text.
How can I do this?
An example of what I'm trying to do...
$value = 'text|0||#fd9||right';
Ok,
text is something that should never change in here.
0, again not changeable
#fd9 is a user-defined string that can be anything that the user inputs...
and right sets the orientation (either left or right).
So, the problem I'm facing is this: How to explode("||", $value) so that if there is a || within the user-defined part... Example:
$value = 'text|0||Just some || text in here||right';
So, if the user places the || in the user-defined part of the string, than this messes this up. How to do this no matter what the user inputs into the string? So that it should return the following array:
array('text|0', 'Just some || text in here', 'right');
Should I be using different character(s) to explode from? If so, what can I use that the user will not be able to input into the string, or how can I check for this, and fix it? I probably shouldn't be using || in this case, but what can I use to fix this?
Also, the value will be coming from a string at first, and than from the database afterwards (once saved).
Any Ideas?
The problem of how to represent arbitrary data types as strings always runs up against exactly the problem you're describing and it has been solved in many ways already. This process is called serialization and there are many serialization formats, anything from PHP's native serialize to JSON to XML. All these formats specify how to present complex data structures as strings, including escaping rules for how to use characters that have a special meaning in the serialization format in the serialized values themselves.
From the comments:
Ok, well, basically, it's straight forward. I already outlined 13 of the other parameters and how they work in Dream Portal located here: http://dream-portal.net/topic_122.0.html so, you can see how they fit in. I'm working on a fieldset parameter that basically uses all of these parameters and than some to include multiple parameters into 1. Anyways, hope that link helps you, for an idea of what an XML file looks like for a module: http://dream-portal.net/topic_98.0.html look at the info.xml section, pay attention to the <param> tag in there, at the bottom, 2 of them.
It seems to me that a more sensible use of XML would make this a lot easier. I haven't read the whole thing in detail, but an XML element like
<param name="test_param" type="select">0:opt1;opt2;opt3</param>
would make much more sense written as
<select name="test_param">
<option default>opt1</option>
<option>opt2</option>
<option>opt3</option>
</select>
Each unique configuration option can have its own unique element namespace with custom sub-elements depending on the type of parameter you need to represent. Then there's no need to invent a custom mini-format for each possible parameter. It also allows you to create a formal XML schema (whether this will do you any good or not is a different topic, but at least you're using XML as it was meant to be used).
You can encode any user input to base64 and then use it with explode or however you wish.
print base64_encode("abcdefghijklmnopqrstuvwxyz1234567890`~!##$%^&*()_+-=[];,./?>:}{<");
serialized arrays are also not a bad idea at all. it's probably better than using a comma separated string and explode. Drupal makes good use of serialized arrays.
take a look at the PHP manual on how to use it:
serialize()
unserialize()
EDIT: New Solution
Is it a guarantee that text doesn't contain || itself?
If it doesn't, you can use substr() in combination with strpos() and strrpos() instead of explode
Here's what I usually do to get around this problem.
1) capture user's text and save it in a var $user_text;
2) run an str_replace() on $user_text to replace the characters you want to split by:
//replace with some random string the user would hopefully never enter
$modified = str_replace('||','{%^#',$user_text);
3) now you can safely explode your text using ||
4) now run an str_replace on each part of the explode, to set it back to the original user entered text
foreach($parts as &$part) {
$part = str_replace('{%^#','||',$part);
}

Categories