PHP array in a query - php

Is there any way, to make something like:
$elements_string = array()
foreach ($something as $element => $value ) {
$elements_string[$element] = $value;
...
}
And save $elements_string into a db row?
Maybe you guys prefer some other way?
I wan't to read it from the database so I can easly parse the string.
Earlier I was using something similar to:
$elements_string = $element . ":" . $value;
And I was trying to use explode on that, but that makes no sense because I need to have $element and $value in one loop for one element.

Normally you would store each element and value in a different row.
If you must store them in one row (and be sure you really have to do that), then use serialize() http://www.php.net/serialize to turn an array into a string you can store.
You can do other things to like: value:element;value:element - then you first split by semicolon, then by colon.

You could use implode(glue,pieces) to turn an array into a string with a given separator, supposing you have a character you never use. (and explode(delimiter,string) to get it back)
Serializing may be a better option in most cases, though. Use serialize(value) to store it and unserialize(value) to get it back.

Related

Stringing together variables, str_replace. Tidier way to do this?

I have a bunch of variables that I want to string together. They all need to be tidied up by removing spaces and commas, and converting to dashes (I'm constructing a URL).
I have a very basic understanding of PHP, but I feel my code below could be tidier and more efficient. Could you point me to some resources or make some suggestions please?
Here's what I have:
$propNum = $prop->Address->Number;
$propStreet = $prop->Address->Street;
$propTown = $prop->Address->Town;
$propPost = $prop->Address->Postcode;
$propFullAdd = array($propNum, $propStreet, $propTown, $propPost);
$propFullAddImp = implode(" ",$propFullAdd);
$propFullAddTidy = str_replace(str_split(' ,'),'-', strtolower($propFullAddImp));
echo $propFullAddTidy;
From the output of your existing code, it seems like you may want an output that looks something like:
12345-example-street-address-example-town-example-postcode
In this case, you could use this solution:
//loop through all the values of $prop->Address
foreach($prop->Address as $value) {
//for each value, replace commas & space with dash
//store altered value in new array `$final_prop`
$final_prop[] = str_replace([' ', ','], '-', $value);
/*
Removing `str_split(' ,')` and subbing an array makes the loop "cheaper" to do,
Because the loop doesn't have to call the `str_split()` function on every iteration.
*/
}
//implode `$final_prop` array to dash separated string
//also lowercase entire string at once (cheaper than doing it in the loop)
$final_prop = strtolower(implode('-', $final_prop));
echo $final_prop;
if you remove the comments, this solution is only 4 lines (instead of 7), and is completely dynamic. This means if you add more values to $prop->Address, you don't have to change anything in this code.
A different method
I feel like this would usually be handled by using http_build_query(), which converts an array into a proper URL-encoded query string. This means that each value in the array would be passed as it's own variable in the URL query.
First, $propFullAdd is not necessary (in fact, it may be detrimental), $prop->Address already contains the exact same array. Recreating the array like this completely removes the ability to tell which value goes to which key, which could be problematic.
This means that you can simplify your entire code by replacing it with this:
echo http_build_query($prop->Address);
Which outputs something like this:
Number=12345&Street=Example+Street+Address&Town=Example+Town&Postcode=Example+Postcode

How to get value of an associative HTML array in PHP using a string?

Look I have a form like this:
<form method="post">
<input name="variable[var1][var2]" value="44"/>
</form>
I want to get the value of variable[var1][var2] in PHP using a string like:
$str = "['variable']['var1']['var2']";
echo "{$_POST{$str}}";
Why I need to do that?
I need it because the code that gets the value is totally dynamic and I cannot get or set manually the value using $_POST['variable']['var1']['var2'].
Can you help?
NOTE: I know this is possible to get it using $_POST['variable']['var1']['var2'], please don't ask me about why I'm not using this way. Simply I need to use as above (using $str).
You can use preg_match_all() to get all the indexes in the string into an array:
$indexes = preg_match_all('/(?<=\[\')(?:[^\']*)(?=\'\])/', $str);
$indexes = $indexes[0]; // Get just the whole matches
Then use a loop to drill into $_POST.
$cur = $_POST;
foreach ($indexes as $index) {
$cur = $cur[$index];
}
At this point $cur will contain the value you want.
You're WAY overthinking it. Anything you put in [] array notation in a form field's name will just become an array key. The following is LITERALLY all you need:
<input name="foo[bar][baz][qux]" ... />
$val = $_POST['foo']['bar']['baz']['qux'];
You cannot use a string as an "address" into the array, not without insanely ugly hacks like eval, or parsing the string and doing a loop to dig into the array.
It's hard to believe that this is a requirement. If you could expand more on what you're trying to achieve, someone undoubtedly has a better solution. However, I will ignore the eval = evil haters.
To echo:
eval("echo \$_POST$str;");
To assign to a variable:
eval("\$result = \$_POST$str;");
If you're open to another syntax then check How to write getter/setter to access multi-level array by key names?

Getting one value out of a serialized array in PHP

What would you say is the most efficient way to get a single value out of an Array. I know what it is, I know where it is. Currently I'm doing it with:
$array = unserialize($storedArray);
$var = $array['keyOne'];
Wondering if there is a better way.
You are doing it fine, I can't think of a better way than what you are doing.
You unserialize
You get an array
You get value by specifying index
That's the way it can be done.
Wondering if there is a better way.
For the example you give with the array, I think you're fine.
If the serialized string contains data and objects you don't want to unserialize (e.g. creating objects you really don't want to have), you can use the Serialized PHP library which is a complete parser for serialized data.
It offers low-level access to serialized data statically, so you can only extract a subset of data and/or manipulate the serialized data w/o unserializing it. However that looks too much for your example as you only have an array and you don't need to filter/differ too much I guess.
Its most efficient way you can do, unserialize and get data, if you need optimize dont store all variables serialized.
Also there is always way to parse it with regexp :)
If you dont want to unseralize the whole thing (which can be costly, especially for more complex objects), you can just do a strpos and look for the features you want and extract them
Sure.
If you need a better way - DO NOT USE serialized arrays.
Serialization is just a transport format, of VERY limited use.
If you need some optimized variant - there are hundreds of them.
For example, you can pass some single scalar variable instead of whole array. And access it immediately
I, too, think the right way is to un-serialize.
But another way could be to use string operations, when you know what you want from the array:
$storedArray = 'a:2:{s:4:"test";s:2:"ja";s:6:"keyOne";i:5;}';
# another: a:2:{s:4:"test";s:2:"ja";s:6:"keyOne";s:3:"sdf";}
$split = explode('keyOne', $storedArray, 2);
# $split[1] contains the value and junk before and after the value
$splitagain = explode(';', $split[1], 3);
# $splitagain[1] should be the value with type information
$value = array_pop(explode(':', $splitagain[1], 3));
# $value contains the value
Now, someone up for a benchmark? ;)
Another way might be RegEx ?

Extracting array with a suffix

Generally, we can extract an array, and also add an prefix to it, like this
extract($array, EXTR_PREFIX_ALL, "myprefix");
// which will give me output like $myprefix_myarrayvar
But, instead, is there a way to set a suffix instead of prefix? Something like,
$myarrayvar_mypostfix;
First of all, you should never use extract because it can make it very hard to tell where some variables are coming from, never mind possible collisions. You don't save much with extract .. it's really just a tool of laziness.
Anyway, since you asked, no there does not seem to be a way to add a suffix with extract natively, so you would have to do it on your own:
foreach ($array as $key => $val) {
${"{$key}_suffix"} = $val;
}
There is no extract option for that. So you need a workaround. You could either write a boring foreach or prepare the keys prior extraction:
extract( array_combine(preg_replace('/$/', "_suffix", array_keys($array)), $array) );

remove duplicate from string in PHP

I am looking for the fastest way to remove duplicate values in a string separated by commas.
So my string looks like this;
$str = 'one,two,one,five,seven,bag,tea';
I can do it be exploding the string to values and then compare, but I think it will be slow. what about preg_replace() will it be faster? Any one did it using this function?
The shortest code would be:
$str = implode(',',array_unique(explode(',', $str)));
If it is the fastest... I don't know, it is probably faster then looping explicitly.
Reference: implode, array_unique, explode
Dealing with: $string = 'one,two,one,five,seven,bag,tea';
If you are generating the string at any point "up script", then you should be eliminating duplicates as they occur.
Let's say you are using concatenation to generate your string like:
$string='';
foreach($data as $value){
$string.=(strlen($string)?',':'').some_func($value);
}
...then you would need to extract unique values from $string based on the delimiter (comma), then re-implode with the delimiter.
I suggest that you design a more direct method and deny duplicates inside of the initial foreach loop, like this:
foreach($data as $value){
$return_value=some_func($value); // cache the returned value so you don't call the function twice
$array[$return_value]=$return_value; // store the return value in a temporary array using the function's return value as both the key and value in the array.
}
$string=implode(',',$array); // clean: no duplicates, no trailing commas
This works because duplicate values are never permitted to exist. All subsequent occurrences will be used to overwrite the earlier occurrence. This function-less filter works because arrays may not have two identical keys in the same array(level).
Alternatively, you can avoid "overwriting" array data in the loop, by calling if(!isset($array[$return_value])){$array[$return_value]=$return_value;} but the difference means calling the isset() function on every iteration. The advantage of using these associative key assignments is that the process avoids using in_array() which is slower than isset().
All that said, if you are extracting a column of data from a 2-dimensional array like:
$string='';
foreach($data as $value){
$string.=(strlen($string)?',':'').$value['word'];
}
Then you could leverage the magic of array_column() without a loop like this:
echo implode(',',array_column($str,'word','word'));
And finally, for those interested in micro-optimization, I'll note that the single call of array_unique() is actually slower than a few two-function methods. Read here for more details.
The bottomline is, there are many ways to perform this task. explode->unique->implode may be the most concise method in some cases if you aren't generating the delimited string, but it is not likely to be the most direct or fastest method. Choose for yourself what is best for your task.

Categories