Related
I have an array:
$a = array('foo' => 'fooMe');
and I do:
print_r($a);
which prints:
Array ( [foo] => printme )
Is there a function, so when doing:
needed_function(' Array ( [foo] => printme )');
I will get the array array('foo' => 'fooMe'); back?
I actually wrote a function that parses a "stringed array" into an actual array. Obviously, it's somewhat hacky and whatnot, but it works on my testcase. Here's a link to a functioning prototype at http://codepad.org/idlXdij3.
I'll post the code inline too, for those people that don't feel like clicking on the link:
<?php
/**
* #author ninetwozero
*/
?>
<?php
//The array we begin with
$start_array = array('foo' => 'bar', 'bar' => 'foo', 'foobar' => 'barfoo');
//Convert the array to a string
$array_string = print_r($start_array, true);
//Get the new array
$end_array = text_to_array($array_string);
//Output the array!
print_r($end_array);
function text_to_array($str) {
//Initialize arrays
$keys = array();
$values = array();
$output = array();
//Is it an array?
if( substr($str, 0, 5) == 'Array' ) {
//Let's parse it (hopefully it won't clash)
$array_contents = substr($str, 7, -2);
$array_contents = str_replace(array('[', ']', '=>'), array('#!#', '#?#', ''), $array_contents);
$array_fields = explode("#!#", $array_contents);
//For each array-field, we need to explode on the delimiters I've set and make it look funny.
for($i = 0; $i < count($array_fields); $i++ ) {
//First run is glitched, so let's pass on that one.
if( $i != 0 ) {
$bits = explode('#?#', $array_fields[$i]);
if( $bits[0] != '' ) $output[$bits[0]] = $bits[1];
}
}
//Return the output.
return $output;
} else {
//Duh, not an array.
echo 'The given parameter is not an array.';
return null;
}
}
?>
If you want to store an array as string, use serialize [docs] and unserialize [docs].
To answer your question: No, there is no built-in function to parse the output of print_r into an array again.
No. But you can use both serialize and json_* functions.
$a = array('foo' => 'fooMe');
echo serialize($a);
$a = unserialize($input);
Or:
echo json_encode($a);
$a = json_decode($input, true);
you cannot do this with print_r,
var_export should allow something similar, but not exactly what you asked for
http://php.net/manual/en/function.var-export.php
$val = var_export($a, true);
print_r($val);
eval('$func_val='.$val.';');
There is a nice Online-Tool which does exatly what its name is:
print_r to json online converter
From a JSON Object its not far to creating an array with the json_decode function:
To get an array from this, set the second paramter to true. If you don't, you will get an object instead.
json_decode($jsondata, true);
I think my function is cool too, works with nested arrays:
function print_r_reverse($input)
{
$output = str_replace(['[', ']'], ["'", "'"], $input);
$output = preg_replace('/=> (?!Array)(.*)$/m', "=> '$1',", $output);
$output = preg_replace('/^\s+\)$/m', "),\n", $output);
$output = rtrim($output, "\n,");
return eval("return $output;");
}
NB: better not use this with user input data
Here is a print_r output parser, producing the same expression in PHP syntax. It is written as an interactive Stack Snippet, so you can use it here:
function parse(s) {
const quote = s => '"' + s.replace(/["\\]/g, '\\$&') + '"';
const compress = indent => " ".repeat(((indent.length + 4) >> 3) * 4);
return "$data = " + (s.replace(/\r\n?/g, "\n") + "\n").replace(
/(Array|\w+ (Object)) *\n *\( *\n|^( *)(?:\[(?:(0|-?[1-9]\d*)|(.*?))\] => |(\) *\n+))|(-?\d+(?:\.\d+)?(?:E[-+]\d+)?)\n|(.*(?:\n(?! *\) *$| *\[.*?\] => ).*)*)\n/gm,
(_, array, object, indent, index, key, close, number, string) =>
object ? "(object) [\n"
: array ? "[\n"
: close ? compress(indent) + "],\n"
: indent ? compress(indent) + (index ?? quote(key)) + " => "
: (number ?? quote(string)) + ",\n"
).replace(/,\n$/, ";");
}
// I/O handling
const [input, output] = document.querySelectorAll("textarea");
(input.oninput = () => output.value = parse(input.value))();
textarea { width: 23em; height: 12em }
<table><tr><th>Input print_r format</th><th>Output PHP syntax</th></tr>
<tr><td><textarea>
Array
(
[0] => example
[1] => stdClass Object
(
[a[] => 1.43E+19
["] => quote
[] =>
)
)
</textarea></td><td><textarea readonly></textarea></td></tr></table>
Remarks
Don't remove any line breaks from the original print_r output. For instance, both the opening and closing parentheses after Array must appear on separate lines.
Don't change the spacing around => (one space before, one after).
As print_r does not distinguish between null, "" or false (it produces no output for these values), nor between true and 1 (both are output as 1), this converter will never produce null, false or true.
As print_r does not distinguish between numbers and strings (9 could represent a number or a string), this converter will assume that the data type is to be numeric when such ambiguity exists.
stdClass Object is supported and translates to (object) [...] notation
MyClass Object will be treated as if it was a stdClass object.
String literals in the output are double quoted and literal double quotes and backslashes are escaped.
Quick function (without checks if you're sending good data):
function textToArray($str)
{
$output = [];
foreach (explode("\n", $str) as $line) {
if (trim($line) == "Array" or trim($line) == "(" or trim($line) == ")") {
continue;
}
preg_match("/\[(.*)\]\ \=\>\ (.*)$/i", $line, $match);
$output[$match[1]] = $match[2];
}
return $output;
}
This is the expected input:
Array
(
[test] => 6
)
This is how I interpreted the question:
function parsePrintedArray($s){
$lines = explode("\n",$s);
$a = array();
foreach ($lines as $line){
if (strpos($line,"=>") === false)
continue;
$parts = explode('=>',$line);
$a[trim($parts[0],'[] ')] = trim($parts[1]);
}
return $a;
}
Works for both objects and arrays:
$foo = array (
'foo' => 'bar',
'cat' => 'dog'
);
$s = print_r($foo,1);
$a = parsePrintedArray($s);
print_r($a);
Output:
Array
(
[foo] => bar
[cat] => dog
)
doesnt work on nested arrays, but simple and fast.
use
var_export(array('Sample array', array('Apple', 'Orange')));
Output:
array (
0 => 'Sample array',
1 =>
array (
0 => 'Apple',
1 => 'Orange',
),
)
json_encode() and json_decode() function will do it.
$asso_arr = Array([779] => 79 => [780] => 80 [782] => 82 [783] => 83);
$to_string = json_encode($asso_arr);
It will be as a json format {"779":"79","780":"80","782":"82","783":"83"}
Then we will convert it into json_decode() then it gives associative array same as original:
print_r(json_decode($to_string));
Output will be Array([779] => 79 => [780] => 80 [782] => 82 [783] => 83) in associative array format.
This is the initial string:-
NAME=Marco\nLOCATION=localhost\nSECRET=fjsdgfsjfdskffuv=\n
This is my solution although the "=" in the end of the string does not appear in the array
$env = file_get_contents(base_path() . '/.env');
// Split string on every " " and write into array
$env = preg_split('/\s+/', $env);
//create new array to push data in the foreach
$newArray = array();
foreach($env as $val){
// Split string on every "=" and write into array
$result = preg_split ('/=/', $val);
if($result[0] && $result[1])
{
$newArray[$result[0]] = $result[1];
}
}
print_r($newArray);
This is the result I get:
Array ( [Name] => Marco [LOCATION] => localhost [SECRET] => fjsdgfsjfdskffuv )
But I need :
Array ( [Name] => Marco [LOCATION] => localhost [SECRET] => fjsdgfsjfdskffuv= )
You can use the limit parameter of preg_split to make it only split the string once
http://php.net/manual/en/function.preg-split.php
you should change
$result = preg_split ('/=/', $val);
to
$result = preg_split ('/=/', $val, 2);
Hope this helps
$string = 'NAME=Marco\nLOCATION=localhost\nSECRET=fjsdgfsjfdskffuv=\n';
$strXlate = [ 'NAME=' => '"NAME":"' ,
'LOCATION=' => '","LOCATION":"',
'SECRET=' => '","SECRET":"' ,
'\n' => '' ];
$jsonified = '{'.strtr($string, $strXlate).'"}';
$array = json_decode($jsonified, true);
This is based on 1) translation using strtr(), preparing an array in json format and then using a json_decode which blows it up nicely into an array...
Same result, other approach...
You can also use parse_str to parse URL syntax-like strings to name-value pairs.
Based on your example:
$newArray = [];
$str = file_get_contents(base_path() . '/.env');
$env = explode("\n", $str);
array_walk(
$env,
function ($i) use (&$newArray) {
if (!$i) { return; }
$tmp = [];
parse_str($i, $tmp);
$newArray[] = $tmp;
}
);
var_dump($newArray);
Of course, you need to put some sanity check in the function since it can insert some strange stuff in the array like values with empty string keys, and whatnot.
I know what you're thinking. "I can answer this question so quick! It's the parse_str function!" But I've got a little twist for you.
You see, PHP converts the names of all query data into valid PHP variable names. What? Even when they're not being stored as variables? Where is that documented? It isn't.
$payload = 'data.name=value&data.other=value2';
parse_str($payload, $values);
var_export($values);
// Outputs: array('data_name' => 'value', 'data_other' => 'value2')
// Expected: array('data.name' => 'value', 'data.other' => 'value2')
How can I parse a query string without this happening?
You can avoid PHP's renaming of parameter names by parsing the query string yourself. Split the string on & and = characters, and then urldecode() each part:
<?php
$payload = 'data.name=value&data.other=value2';
$values = array();
$nv_strings = explode ('&', $payload);
foreach ($nv_strings as $s) {
$nv = explode ('=', $s, 2);
$name = urldecode ($nv[0]);
$value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
$values[$name] = $value;
}
print_r ($values);
// Array
// (
// [data.name] => value
// [data.other] => value2
// )
If your query string contains duplicate keys, the above code will overwrite the previous keys. This also can be solved:
<?php
$payload = 'key=val1&key=val2&key=val3';
$values = array();
$nv_strings = explode ('&', $payload);
foreach ($nv_strings as $s) {
$nv = explode ('=', $s, 2);
$name = urldecode ($nv[0]);
$value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
$values[] = array ($name => $value);
}
print_r ($values);
// Array
// (
// [0] => Array ([key] => val1)
// [1] => Array ([key] => val2)
// [2] => Array ([key] => val3)
// )
You may want to consolidate the duplicate keys into subarrays:
<?php
$payload = 'key1=val1&key1=val2&key2=val3';
$values = array();
$nv_strings = explode ('&', $payload);
foreach ($nv_strings as $s) {
$nv = explode ('=', $s, 2);
$name = urldecode ($nv[0]);
$value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
if (isset ($values[$name])) {
if (is_array ($values[$name])) {
$values[$name][] = $value;
} else {
$values[$name] = array ($values[$name], $value);
}
} else {
$values[$name] = $value;
}
}
print_r ($values);
// Array
// (
// [key1] => Array ([0] => val1
// [1] => val2)
// [key2] => val3
// )
You can simplify the code somewhat by always using subarrays:
<?php
$payload = 'key1=val1&key1=val2&key2=val3';
$values = array();
$nv_strings = explode ('&', $payload);
foreach ($nv_strings as $s) {
$nv = explode ('=', $s, 2);
$name = urldecode ($nv[0]);
$value = (isset ($nv[1]) ? urldecode ($nv[1]) : null);
if (isset ($values[$name])) {
$values[$name][] = $value;
} else {
$values[$name] = array ($value);
}
}
print_r ($values);
// Array
// (
// [key1] => Array ([0] => val1
// [1] => val2)
// [key2] => Array ([0] => val3)
// )
It is documented completely in PHP Documentation for the function parse_str If the output does not work for your particular use case, then you must use another function, or create your own. The key here is that this function parses the string into variables.
parse_str — Parses the string into variables
Parses str as if it were the query string passed via a URL and sets variables in the current scope.
To parse the string you provided, this would work:
$payload = 'data.name=value';
$map = array();
$vals = preg_split('/=/', $payload);
$i= 0;
while($i < count($vals)) {
$map[$vals[$i]] = $vals[++$i];
$i++;
}
var_dump($map);
This question already has answers here:
Create a comma-separated string from a single column of an array of objects
(15 answers)
Closed 7 months ago.
I am wondering how to:
Make comma-separated list
Strip last comma from list
Here's an array example:
Array
(
[name] => Array
(
[0] => Some message to display1
)
[test] => Array
(
[0] => Some message to display2
)
[kudos] => Array
(
[0] => Some message to display3
)
)
I want to display it like this:
Comma-List: Some message to display1, Some message to display2, Some message to display3
Loop through the arrays and implode() after you've got each array.
$bigArray = array();
foreach($firstArray as $secondArray){
if(is_array($secondArray)){
$bigArray = array_merge($bigArray, $secondArray);
}
}
$commaList = implode(",", $bigArray);
so, revising my answer to actually address your question, you could do it with nested foreach loops like this:
<?php
$a1 = array(
'name' => array( 0 => 'Some message to display1'),
'test' => array( 0 => 'Some message to display2'),
'kudos' => array( 0 => 'Some message to display3'),
);
$final = "";
foreach($a1 as $innerarray){
foreach($innerarray as $message){
$final .= $message.", ";
}
}
echo substr($final,0,-2);
?>
You can use implode to join values and array_map to extract them:
// this should be your array
$youArray = array();
// return first elements
$values = array_map(function($item) { return $item[0]; }, $youArray);
// echo joined values
echo implode(',', $values);
$array = array("some text","other text");
$impl = implode(",", $array);
echo $impl;
implode works on 1D arrays, but you have a 2D array, this will take a bit more work.
You can use array_map to flatten the array
$flatArray = array_map(function($a){
// I implode here just in case the arrays
// have more than one element, if it's just one
// you can return '$a[0];' instead
return implode(',', $a);
}, $array);
echo implode(',', $flatArray);
This works for your array and should work for arrays that are n levels deep:
$array = array(
'name' => array('Some message to display1'),
'test' => array('Some message to display2'),
'kudos' => array('Some message to display3')
);
$mystr = multi_join($array);
while (substr($mystr, -1) == ',') {
$mystr = substr($mystr, 0, -1);
}
echo $mystr;
function multi_join($value) {
$string = '';
if (is_array($value)) {
foreach ($value as $el) {
$string.= multi_join($el);
}
} else {
$string.= $value.',';
}
return $string;
}
Simplest for your specific sample data would be to access the 0 column of data and implode that. (Demo)
echo implode(', ', array_column($array, 0));
Here are a couple of additional techniques to add to this heap...
Reindex the first level because the splat operator doesn't like associative keys, then merge the unpacked subarrays, and implode.
Use array_reduce() to iterate the first level and extract the first element from each subarray, delimiting as desired without the use of implode().
Codes: (Demo)
$array = [
'name' => ['Some message to display1'],
'test' => ['Some message to display2'],
'kudos' => ['Some message to display3']
];
echo implode(', ', array_merge(...array_values($array)));
echo "\n---\n";
echo array_reduce($array, function($carry, $item) {return $carry .= ($carry ? ', ' : '') . $item[0]; }, '');
Output:
Some message to display1, Some message to display2, Some message to display3
---
Some message to display1, Some message to display2, Some message to display3
The first technique will accommodate multiple elements in the subarrays, the second will not acknowledge more than one "message" per subarray.
I have several strings, how can I search the first value and get other values from it?
print_r or ?:
Array( [0] => Title,11,11 [1] => Would,22,22 [2] => Post,55,55 [3] => Ask,66,66 )
like:
If send for this array value Title and getting values Title,11,11
Or send Would getting values Would,22,22
Or send Post getting values Post,55,55
Or send Ask getting values Ask,66,66
How can do it?
Loop over the array with foreach and match the value with strpos.
suppose:
$arr = Array( [0] => Title,11,11 [1] => Would,22,22 [2] => Post,55,55 [3] => Ask,66,66 )
$string = 'Would';
then
//Call the function with the search value in $string and the actual array
$required_arr[$string] = search_my_array($string, $arr);
function($str , $array)
{
//Trace the complete array
for($i = 0; $i<count($array); $i++)
{
//Break the array using explode function based on ','
$arr_values[$i] = explode(',',$array[i])
if($str == $arr_values[$i][0]) // Match the First String with the required string
{
//On match return the array with the values contained in it
return array($arr_values[$i][1], $arr_values[$i][2]);
}
}
}
Now
$required_arr['Would'] // will hold Array([0] => 22 [1] => 22)
Write a function to search the array. This should work well enough
<?php
// test array
$arr = array('Title,11,11','Would,22,22','Post,55,55','Ask,66,66');
// define search function that you pass an array and a search string to
function search($needle,$haystack){
// loop over each passed in array element
foreach($haystack as $v){
// if there is a match at the first position
if(strpos($v,$needle) === 0)
// return the current array element
return $v;
}
// otherwise retur false if not found
return false;
}
// test the function
echo search("Would",$arr);
?>
are the indices important ? why not ..
$arr = array(
'Title' => array(11, 11),
'Would' => array(22, 22),
'Post' => array(55, 55),
'Ask' => array(66,66)
);
$send = "Title"; // for example
$result = $arr[$send];
How about using something like, so you don't loop trough entire array:
$array = array( "Title,11,11", "Would,22,22", "Post,55,55", "Ask,66,66" );
$key = my_array_search('Would', $array);
$getvalues = explode(",", $array[$key]);
function my_array_search($needle = null, $haystack_array = null, $skip = 0)
{
if($needle == null || $haystack_array == null)
die('$needle and $haystack_array are mandatory for function my_array_search()');
foreach($haystack_array as $key => $eval)
{
if($skip != 0)$eval = substr($eval, $skip);
if(stristr($eval, $needle) !== false) return $key;
}
return false;
}