Related
I have an array let's say it looks like this:
$arr=array('aa','bb','cc');
Now let's say I have a string that looks like any of these:
$str='bb';
$str='A_STRING_bb_WITH_SOME_TEXT';
$str='ASTRINGbbWITHSOMETEXT';
$str='A+STRING+bb+WITH+SOME+TEXT';
$str='A STRING bb WITH SOME TEXT';
I would like a function that gives me:
$r=find_which_one($arr,$str);
$r should be "bb" for all of those. What's the best way to do this?
Something like this:
function find_which_one($arr,$str){
foreach($arr AS $needle){
if (strpos($str, $needle)){
return true; //returns true on the first match
}
}
return false
}
$arr=array('aa','bb','cc');
$str='A_STRING_bb_WITH_SOME_TEXT aa';
function find_which_one(array $arr,$str) {
$r = preg_match(
'/((' . implode(')|(', $arr) .'))/',
$str,
$matches
);
return ($r !== false) ? $matches[0] : $r;
}
$r=find_which_one($arr,$str);
var_dump($r);
Returns false if not found, else the value from $arr that occurred first
This will return the correct key. If not found, it will return false.
function find_which_one($keys,$value) {
foreach($keys as $key) if (strpos($value, $key)) return $key;
return false;
}
Using array_filter it is straight forward:
$arr = array('aa','bb','cc');
$str = 'A+STRING+bb+WITH+SOME+TEXT';
print_r ( array_filter($arr, function($k) use($str) {
return strpos($str, $k) !== FALSE; }) );
Array
(
[1] => bb
)
Or else:
$str = 'ASTRINGbbWITHSOMETEXT';
print_r ( array_filter($arr, function($k) use($str) {
return strpos($str, $k) !== FALSE; }) );
Array
(
[1] => bb
)
I have this code:
$arr = array("Hello_backup","World!","Beautiful_backup","Day!");
if(in_array("backup", $arr)){
echo "Da";
} else { echo "Nu";
}
But is not working because,in_array instruction check the array for the complete string "backup" , which doesnt exist.I need to check for a part of the string,for example,to return true because backup is a part of the "Hello_backup" and "Beautiful_backup" strings
EDIT: I take the advice and i have used stripos like this:
$arr = array("Hello_backup-2014","World!","Beautiful_backup-2014","Day!");
$word='backup';
if(stripos($arr,$word) !== false){
echo "Da";
} else { echo "Nu";}
but now i get an error: "stripos() expects parameter 1 to be string, array given in if(stripos($arr,$word) !== false){"
Use implode to basically concatenate the array values as a string, then use strpos to check for a string within a string.
The first argument you pass to implode is used to separate each value in the array.
$array = array("Hello_backup","World!","Beautiful_backup","Day!");
$r = implode(" ", $array);
if (strpos($r, "backup") !== false) {
echo "found";
}
In this case you need to use stripos(). Example:
$arr = array("Hello_backup","World!","Beautiful_backup","Day!");
$needle = 'backup';
function check($haystack, $needle) {
foreach($haystack as $word) {
if(stripos($word, $needle) !== false) {
return 'Da!'; // if found
}
}
return 'Nu'; // if not found
}
var_dump(check($arr, $needle));
Without a function:
$arr = array("Hello_backup","World!","Beautiful_backup","Day!");
$found = false;
foreach($arr as $word) {
if(stripos($word, 'backup') !== false) {
$found = true;
break;
}
}
if($found) {
echo 'Da!';
} else {
echo 'Nu';
}
Try with strpos()
$arr = array("Hello_backup","World!","Beautiful_backup","Day!");
foreach($arr as $v){
echo (strpos($v,"backup")!== false ? "Da" : "Nu");
}
output :- DaNuDaNu
Here is the one line solution for you.
$arr = array("Hello_backup-2014","World!","Beautiful_backup-2014","Day!");
$returned_a = array_map(function($u){ if(stripos($u,'backup') !== false) return "Da"; else return "Nu";}, $arr);
You can use $returned_a with array as your answer..
Array ( [0] => Da [1] => Nu [2] => Da [3] => Nu )
Use this method. It is little bit simple to use.
$matches = preg_grep('/backup/', $arr);
$keys = array_keys($matches);
print_r($matches);
Look this working example
According to your question
$matches = preg_grep('/backup/', $arr);
$keys = array_keys($matches);
$matches = trim($matches);
if($matches != '')
{echo "Da";
}else { echo "Nu";}
<?php
$arr = array("Hello_backup","World!","Beautiful_backup","Day!");
foreach($arr as $arr1) {
if (strpos ($arr1,"backup")) {
echo "Da";
} else {
echo "Nu";
}
}
?>
I know how to find if your string equals an array value:
$colors = array("blue","red","white");
$string = "white";
if (!in_array($string, $colors)) {
echo 'not found';
}
...but how do I find if the string CONTAINS any part of the array values?
$colors = array("blue","red","white");
$string = "whitewash"; // I want this to be found in the array
if (!in_array($string, $colors)) {
echo 'not found';
}
Or in one shot:
if( preg_match("(".implode("|",array_map("preg_quote",$colors)).")",$string,$m)) {
echo "Found ".$m[0]."!";
}
This can also be expanded to only allow words that start with an item from your array:
if( preg_match("(\b(?:".implode("|",array_map("preg_quote",$colors))."))",$string,$m)) {
Or case-insensitive:
if( preg_match("(".implode("|",array_map("preg_quote",$colors)).")i",$string,$m)) {
CI with starting only:
if( preg_match("(\b(?:".implode("|",array_map("preg_quote",$colors))."))i",$string,$m)) {
Or anything really ;)
Just loop the array containing the values, and check if they are found in the input string, using strpos
$colors = array("blue","red","white");
$string = "whitewash"; // I want this to be found in the array
foreach ( $colors as $c ) {
if ( strpos ( $string , $c ) !== FALSE ) {
echo "found";
}
}
You can wrap it in a function:
function findString($array, $string) {
foreach ( $array as $a ) {
if ( strpos ( $string , $a ) !== FALSE )
return true;
}
return false;
}
var_dump( findString ( $colors , "whitewash" ) ); // TRUE
Try this working solution
$colors = array("blue", "red", "white");
$string = "whitewash";
foreach ($colors as $color) {
$pos = strpos($string, $color);
if ($pos === false) {
echo "The string '$string' not having substring '$color'.<br>";
} else {
echo "The string '$string' having substring '$color'.<br>";
}
}
There is no built-in function for that, but you could do something like:
$colors = array("blue","red","white");
$string = "whitewash"; // I want this to be found in the array
if (!preg_match('/\Q'.implode('\E|\Q',$colors).'\E/',$string)) {
echo 'not found';
}
This basically makes a regex from your array and matches the string against it. Good method, unless your array is really large.
You would have to iterate over each array element and individually check if it contains it (or a substr of it).
This is similar to what you want to do:
php check if string contains a value in array
$colors = array("blue","red","white");
$string = "whitewash"; // I want this to be found in the array
$hits = array();
foreach($colors as $color) {
if(strpos($string, $color) !== false) {
$hits[] = $color;
}
}
$hits will contain all $colors that have a match in $string.
if(empty($hits)) {
echo 'not found';
}
I have trouble reading Postgresql arrays in PHP. I have tried explode(), but this breaks arrays containing commas in strings, and str_getcsv() but it's also no good as PostgreSQL doesn't quote the Japanese strings.
Not working:
explode(',', trim($pgArray['key'], '{}'));
str_getcsv( trim($pgArray['key'], '{}') );
Example:
// print_r() on PostgreSQL returned data: Array ( [strings] => {または, "some string without a comma", "a string, with a comma"} )
// Output: Array ( [0] => または [1] => "some string without a comma" [2] => "a string [3] => with a comma" )
explode(',', trim($pgArray['strings'], '{}'));
// Output: Array ( [0] => [1] => some string without a comma [2] => a string, with a comma )
print_r(str_getcsv( trim($pgArray['strings'], '{}') ));
If you have PostgreSQL 9.2 you can do something like this:
SELECT array_to_json(pg_array_result) AS new_name FROM tbl1;
The result will return the array as JSON
Then on the php side issue:
$array = json_decode($returned_field);
You can also convert back. Here are the JSON functions page
As neither of these solutions work with multidimentional arrays, so I offer here my recursive solution that works with arrays of any complexity:
function pg_array_parse($s, $start = 0, &$end = null)
{
if (empty($s) || $s[0] != '{') return null;
$return = array();
$string = false;
$quote='';
$len = strlen($s);
$v = '';
for ($i = $start + 1; $i < $len; $i++) {
$ch = $s[$i];
if (!$string && $ch == '}') {
if ($v !== '' || !empty($return)) {
$return[] = $v;
}
$end = $i;
break;
} elseif (!$string && $ch == '{') {
$v = pg_array_parse($s, $i, $i);
} elseif (!$string && $ch == ','){
$return[] = $v;
$v = '';
} elseif (!$string && ($ch == '"' || $ch == "'")) {
$string = true;
$quote = $ch;
} elseif ($string && $ch == $quote && $s[$i - 1] == "\\") {
$v = substr($v, 0, -1) . $ch;
} elseif ($string && $ch == $quote && $s[$i - 1] != "\\") {
$string = false;
} else {
$v .= $ch;
}
}
return $return;
}
I haven't tested it too much, but looks like it works.
Here you have my tests with results:
var_export(pg_array_parse('{1,2,3,4,5}'));echo "\n";
/*
array (
0 => '1',
1 => '2',
2 => '3',
3 => '4',
4 => '5',
)
*/
var_export(pg_array_parse('{{1,2},{3,4},{5}}'));echo "\n";
/*
array (
0 =>
array (
0 => '1',
1 => '2',
),
1 =>
array (
0 => '3',
1 => '4',
),
2 =>
array (
0 => '5',
),
)
*/
var_export(pg_array_parse('{dfasdf,"qw,,e{q\"we",\'qrer\'}'));echo "\n";
/*
array (
0 => 'dfasdf',
1 => 'qw,,e{q"we',
2 => 'qrer',
)
*/
var_export(pg_array_parse('{,}'));echo "\n";
/*
array (
0 => '',
1 => '',
)
*/
var_export(pg_array_parse('{}'));echo "\n";
/*
array (
)
*/
var_export(pg_array_parse(null));echo "\n";
// NULL
var_export(pg_array_parse(''));echo "\n";
// NULL
P.S.: I know this is a very old post, but I couldn't find any solution for postgresql pre 9.2
Reliable function to parse PostgreSQL (one-dimensional) array literal into PHP array, using regular expressions:
function pg_array_parse($literal)
{
if ($literal == '') return;
preg_match_all('/(?<=^\{|,)(([^,"{]*)|\s*"((?:[^"\\\\]|\\\\(?:.|[0-9]+|x[0-9a-f]+))*)"\s*)(,|(?<!^\{)(?=\}$))/i', $literal, $matches, PREG_SET_ORDER);
$values = [];
foreach ($matches as $match) {
$values[] = $match[3] != '' ? stripcslashes($match[3]) : (strtolower($match[2]) == 'null' ? null : $match[2]);
}
return $values;
}
print_r(pg_array_parse('{blah,blah blah,123,,"blah \\"\\\\ ,{\100\x40\t\daő\ő",NULL}'));
// Array
// (
// [0] => blah
// [1] => blah blah
// [2] => 123
// [3] =>
// [4] => blah "\ ,{## daőő
// [5] =>
// )
var_dump(pg_array_parse('{,}'));
// array(2) {
// [0] =>
// string(0) ""
// [1] =>
// string(0) ""
// }
print_r(pg_array_parse('{}'));
var_dump(pg_array_parse(null));
var_dump(pg_array_parse(''));
// Array
// (
// )
// NULL
// NULL
print_r(pg_array_parse('{または, "some string without a comma", "a string, with a comma"}'));
// Array
// (
// [0] => または
// [1] => some string without a comma
// [2] => a string, with a comma
// )
If you can foresee what kind text data you can expect in this field, you can use array_to_string function. It's available in 9.1
E.g. I exactly know that my array field labes will never have symbol '\n'. So I convert array labes into string using function array_to_string
SELECT
...
array_to_string( labels, chr(10) ) as labes
FROM
...
Now I can split this string using PHP function explode:
$phpLabels = explode( $pgLabes, "\n" );
You can use any sequence of characters to separate elements of array.
SQL:
SELECT
array_to_string( labels, '<--###DELIMITER###-->' ) as labes
PHP:
$phpLabels = explode( '<--###DELIMITER###-->', $pgLabes );
As #Kelt mentioned:
Postgresql arrays look like this: {1,2,3,4}
You can just simply replace first { and last } with [ and ]
respectively and then json_decode that.
But his solution works only for one-dimensional arrays.
Here the solution either for one-dimensional and multidimensional arrays:
$postgresArray = '{{1,2},{3,4}}';
$phpArray = json_decode(str_replace(['{', '}'], ['[', ']'], $postgresArray)); // [[1,2],[3,4]]
To cast back:
$phpArray=[[1,2],[3,4]];
$postgresArray=str_replace(['[', ']'], ['{', '}'], json_encode($phpArray));
Based on the answers in the thread i created two simple php functions that can be of use:
private function pgArray_decode(string $pgArray){
return explode(',', trim($pgArray, '{}'));
}
private function pgArray_encode(array $array){
$jsonArray = json_encode($array, true);
$jsonArray = str_replace('[','{',$jsonArray);
$jsonArray = str_replace(']','}',$jsonArray);
return $jsonArray;
}
I tried the array_to_json answer, but unfortunalety this results in an unknown function error.
Using the dbal query builder on a postgres 9.2 database with something like ->addSelect('array_agg(a.name) as account_name'), I got as result a string like { "name 1", "name 2", "name 3" }
There are only quotes around the array parts if they contain special characters like whitespace or punctuation.
So if there are quotes, I make the string a valid json string and then use the build-in parse json function. Otherwise I use explode.
$data = str_replace(array("\r\n", "\r", "\n"), "", trim($postgresArray,'{}'));
if (strpos($data, '"') === 0) {
$data = '[' . $data . ']';
$result = json_decode($data);
} else {
$result = explode(',', $data);
}
If you have control of the query that's hitting the database, why don't you just use unnest() to get the results as rows instead of Postgres-arrays? From there, you can natively get a PHP-array.
$result = pg_query('SELECT unnest(myArrayColumn) FROM someTable;');
if ( $result === false ) {
throw new Exception("Something went wrong.");
}
$array = pg_fetch_all($result);
This sidesteps the overhead and maintenance-issues you'd incur by trying to convert the array's string-representation yourself.
I can see you are using explode(',', trim($pgArray, '{}'));
But explode is used to Split a string by string (and you are supplying it an array!!). something like ..
$string = "A string, with, commas";
$arr = explode(',', $string);
What are you trying to do with array? if you want to concatenate have a look on implode
OR not sure if it is possible for you to specify the delimiter other than a comma? array_to_string(anyarray, text)
Postgresql arrays look like this: {1,2,3,4}
You can just simply replace first { and last } with [ and ] respectively and then json_decode that.
$x = '{1,2,3,4}';
$y = json_decode('[' . substr($x, 1, -1) . ']'); // [1, 2, 3, 4]
To cast back the other way would be mirror opposite:
$y = [1, 2, 3, 4];
$x = '{' . substr(json_encode($y), 1, -1) . '}';
A simple and fast function for converting deep PostgreSQL array string to JSON string without using pg connection.
function pgToArray(string $subject) : array
{
if ($subject === '{}') {
return array();
}
$matches = null;
// find all elements;
// quoted: {"1{\"23\"},abc"}
// unquoted: {abc,123.5,TRUE,true}
// and empty elements {,,}
preg_match_all( '/\"((?<=\\\\).|[^\"])*\"|[^,{}]+|(?={[,}])|(?=,[,}])/', $subject,$matches,PREG_OFFSET_CAPTURE);
$subject = str_replace(["{","}"],["[","]"],$subject); // converting delimiters to JSON
$matches = array_reverse($matches[0]);
foreach ($matches as $match) {
$item = trim($match[0]);
$replace = null;
if ((strpos($item,"{") !== false) || (strpos($item,"}") !== false)) {
// restoring replaced '{' and '}' inside string
$replace = $match[0];
} elseif (in_array($item,["NULL","TRUE","FALSE"])) {
$replace = strtolower($item);
} elseif ($item === "" || ($item[0] !== '"' && !in_array($item,["null","true","false"]) && !is_float($item))) {
$replace = '"' . $item . '"'; // adding quotes to string element
}
if ($replace) { // concatenate modified element instead of old element
$subject = substr($subject, 0, $match[1]) . $replace . substr($subject, $match[1] + strlen($match[0]));
}
}
return json_decode($subject, true);
}
I've got a multidimensional associative array which includes an elements like
$data["status"]
$data["response"]["url"]
$data["entry"]["0"]["text"]
I've got a strings like:
$string = 'data["status"]';
$string = 'data["response"]["url"]';
$string = 'data["entry"]["0"]["text"]';
How can I convert the strings into a variable to access the proper array element? This method will need to work across any array at any of the dimensions.
PHP's variable variables will help you out here. You can use them by prefixing the variable with another dollar sign:
$foo = "Hello, world!";
$bar = "foo";
echo $$bar; // outputs "Hello, world!"
Quick and dirty:
echo eval('return $'. $string . ';');
Of course the input string would need to be be sanitized first.
If you don't like quick and dirty... then this will work too and it doesn't require eval which makes even me cringe.
It does, however, make assumptions about the string format:
<?php
$data['response'] = array(
'url' => 'http://www.testing.com'
);
function extract_data($string) {
global $data;
$found_matches = preg_match_all('/\[\"([a-z]+)\"\]/', $string, $matches);
if (!$found_matches) {
return null;
}
$current_data = $data;
foreach ($matches[1] as $name) {
if (key_exists($name, $current_data)) {
$current_data = $current_data[$name];
} else {
return null;
}
}
return $current_data;
}
echo extract_data('data["response"]["url"]');
?>
This can be done in a much simpler way. All you have to do is think about what function PHP provides that creates variables.
$string = 'myvariable';
extract(array($string => $string));
echo $myvariable;
done!
You can also use curly braces (complex variable notation) to do some tricks:
$h = 'Happy';
$n = 'New';
$y = 'Year';
$wish = ${$h.$n.$y};
echo $wish;
Found this on the Variable variables page:
function VariableArray($data, $string) {
preg_match_all('/\[([^\]]*)\]/', $string, $arr_matches, PREG_PATTERN_ORDER);
$return = $arr;
foreach($arr_matches[1] as $dimension) { $return = $return[$dimension]; }
return $return;
}
I was struggling with that as well,
I had this :
$user = array('a'=>'alber', 'b'=>'brad'...);
$array_name = 'user';
and I was wondering how to get into albert.
at first I tried
$value_for_a = $$array_name['a']; // this dosen't work
then
eval('return $'.$array_name['a'].';'); // this dosen't work, maybe the hoster block eval which is very common
then finally I tried the stupid thing:
$array_temp=$$array_name;
$value_for_a = $array_temp['a'];
and this just worked Perfect!
wisdom, do it simple do it stupid.
I hope this answers your question
You would access them like:
print $$string;
You can pass by reference with the operator &. So in your example you'll have something like this
$string = &$data["status"];
$string = &$data["response"]["url"];
$string = &$data["entry"]["0"]["text"];
Otherwise you need to do something like this:
$titular = array();
for ($r = 1; $r < $rooms + 1; $r ++)
{
$title = "titular_title_$r";
$firstName = "titular_firstName_$r";
$lastName = "titular_lastName_$r";
$phone = "titular_phone_$r";
$email = "titular_email_$r";
$bedType = "bedType_$r";
$smoker = "smoker_$r";
$titular[] = array(
"title" => $$title,
"first_name" => $$firstName,
"last_name" => $$lastName,
"phone" => $$phone,
"email" => $$email,
"bedType" => $$bedType,
"smoker" => $$smoker
);
}
There are native PHP function for this:
use http://php.net/manual/ru/function.parse-str.php (parse_str()).
don't forget to clean up the string from '"' before parsing.
Perhaps this option is also suitable:
$data["entry"]["0"]["text"];
$string = 'data["entry"]["0"]["text"]';
function getIn($arr, $params)
{
if(!is_array($arr)) {
return null;
}
if (array_key_exists($params[0], $arr) && count($params) > 1) {
$bf = $params[0];
array_shift($params);
return getIn($arr[$bf], $params);
} elseif (array_key_exists($params[0], $arr) && count($params) == 1) {
return $arr[$params[0]];
} else {
return null;
}
}
preg_match_all('/(?:(\w{1,}|\d))/', $string, $arr_matches, PREG_PATTERN_ORDER);
array_shift($arr_matches[0]);
print_r(getIn($data, $arr_matches[0]));
P.s. it's work for me.