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

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.

Related

Getting value from string by index

I have a string of data formatted like so:
[{"pr_a_w":"10","pr_a_we":"10","pr_c_w":"10","pr_c_we":"10"},{"pr_a_w":"20","pr_a_we":"20","pr_c_w":"20","pr_c_we":"20"},{"pr_a_w":"111","pr_a_we":"11","pr_c_w":"111","pr_c_we":"111"}]
The string doesn't have any index/numbers like a regular array would and I'm finding it difficult to extract individual values e.g. with a regular array I could use:
$string[0]["pr_a_w"]
To get the first instance of "pr_a_w" and I could use:
$string[1]["pr_a_w"]
To get the second instance etc.
Is it possible to get single values from this string based on their number?
What you have there is valid JSON (serialized array of objects), so you could use json_decode to translate the serialized data into a native PHP array:
$array = json_decode('[{"pr_a_w":"10","pr_a_we":"10","pr_c_w":"10","pr_c_we":"10"},{"pr_a_w":"20","pr_a_we":"20","pr_c_w":"20","pr_c_we":"20"},{"pr_a_w":"111","pr_a_we":"11","pr_c_w":"111","pr_c_we":"111"}]',true);
$array will then allow you to do exactly what you stated you'd like to do above.
$array[0]["pr_a_w"]; // will give you 10
$array[1]["pr_a_w"]; // will give you 10
Try like this, No need to access with array index. You will get error if you access wrong index.
$json_arr= json_decode('[{"pr_a_w":"10","pr_a_we":"10","pr_c_w":"10","pr_c_we":"10"},{"pr_a_w":"20","pr_a_we":"20","pr_c_w":"20","pr_c_we":"20"},{"pr_a_w":"111","pr_a_we":"11","pr_c_w":"111","pr_c_we":"111"}]',true);
foreach($json_arr as $row){
echo $row['pr_a_w']."<br>";
}

php - Datastore: TextProperty (is there such a thing?)

I need to store a long text/string in google Datastore. This text is a serialized associative array which is 6.40 KB(more than 500 characters).
I'm using Google AppEngine: PHP and google-api-php-client library.
What I've done so far is using these ways:
stringValue
stringValue + indexed = false;
blobValue
blobValue + indexed = false;
blobValue + blobKeyValue
But I don't get any result in lookup(). When I leave the indexed property as default, I don't get any peroperty in the result set, and when I set it to false(unindexed), I just get indexed property back and no other value. When I also check the Developers Console, it shows Unknown for the property value type.
There is something similar to what I need in Python developer's guide:"
class TextProperty()
A long string.
Unlike StringProperty, a TextProperty value can be more than 500 characters long. However, TextProperty values are not indexed and cannot be used in filters or sort orders.
Any idea? please!
You can use stringValue for both indexed and unindexed string values, but indexed values must be <= 500 characters.
To insert a string property longer than 500 characters, you must explicitly set indexed to false, otherwise Cloud Datastore will not accept the entity.
https://developers.google.com/datastore/docs/concepts/entities#Datastore_Properties_and_value_types

REALbasic array in an array

I am trying to write a soap parameter in REALbasic.
I need to add an array within another array similar to this in php:
$params = array(array(
'sku' => 'some sku'
));
so I can pass this:
$result = $client->call($session, 'catalog_product.list', $params);
I have
dim aArgs (0,1) as String
dim aParmas (0,1) as String
aArgs(0,0)="sku"
aArgs(0,1)="some sku"
aParmas(0,1)= aArgs
But receive a "Type mismatch error. Expected String, but got String(,)"
How can I do this.
Thanks
First off, the line
aParmas(0,1)= aArgs
is wrong because you assign an array (which is in aArgs) to a single element of aParmas. And since those single elements hold a String, you try to assign an array to a single string here, hence the error message.
But I think you're looking at this from the wrong end. You need to start with figuring out what parameters you need to send to the session function you want to call.
That means: You need to find the REALbasic function for $client->call. Once you know which function that is, look at the parameters that function expects. I doubt it expects a two-dimensional array for the "params". Once you know what to pass here, let us know if you still cannot figure out how to get it working.
An explanation of multidimensional arrays in REALbasic is here
The short answer is that you can't have a PHP-like array of arrays. You need to wrap your array in a class and make the class behave like an array.
Any reason you're using REALbasic? If it's cross-platform you're after, python is ALWAYS a better choice

How do I parse this string: a:10:{1:0;s:7:"default";i:1; ...?

How can I read strings like that? What do they mean?
a:10:{i:0;s:7:"default";i:1;s:8:"failsafe";i:2;s:4:"foaf";i:3;s:4:"ical";i:4;s:2:"js";i:5;s:4:"json";i:6;s:6:"opendd";i:7;s:3:"php";i:8;s:3:"rss";i:9;s:3:"xml";}
I've seen a lot of systems which use strings like that, stores it in the database and parse to get the values. How can I parse them?
Thanks.
This is a serialized string. Look at the results of var_dump(unserialize()). It is NOT a valid JSON-formatted string (json_decode() will return null).
If you want to actually "read" it without unserializing it, you can see "a:10" means array with 10 indices. "i:0" means "index zero" and is semicolon-separated with the corresponding value ("s:7" is a string of length 7). The values are comma separated. Classes can also be serialized.
It's not JSON, it is a serialized array. Use unserialize() to turn it into something usable.

Unify variable types of array elements

After hours of debugging, I found an error in one of my scripts. For saving different event types in a database, I have an array of unique data for each event that can be used to identify the event.
So I basically have some code like
$key = md5(json_encode($data));
to generate a unique key for each event.
Now, in some cases, a value in the $data array is an integer, sometimes a string (depending on where it comes from - database or URL). That causes the outputs of json_encode() to be different from each other, though - once including quotes, once not.
Does anybody know a way to "unify" the variable types in the $data array? That would probably mean converting all strings that only contain an integer value to integer. Anything else I have to take care of when using json_encode()?
array_walk_recursive combined with a function you have written to the effect of maybe_intval which performs the conversion you talk about on a single element.
EDIT: having read the documentation for array_walk_recursive more closely you'll actually want to write your own recursive function
function to_json($obj){
if(is_object($obj))
$obj=(array)$obj;
if(is_array($obj))
return array_map('to_json',$obj);
return "$obj"; // or return is_int($obj)?intval($obj):$obj;
}

Categories