PHP how to quote string array values - php

If I have the following array $array[0] = array(
"1" => bar,
"2" => foo,
"3" => 13546
); and I implode() it, the value that is returned will be: bar,foo,13546 which cannot be used in a mysql query... How can I place single quotes just to those values that are strings...
I've tryed a couple of ways (like foreach($array as $key=>$value) to check with is_numeric() the $value, and the check is ok but I dont know how to change the value to '$value'...)
Any toughts on this?
EDIT
I found another way to do this for those of you who are interested:
$result[0] = array(
"1" => bar,
"2" => foo,
"3" => 1232.13
);
$copy_r = $result[0];
foreach($copy_r as $key=>$value)
{
if(!is_numeric($value))
{
$insert_array[] = "`$key` = '$value'";
}
else
{
$insert_array[] = "`$key` = $value";
}
}
$final_string = implode(',', $insert_array);
$insert_q = "INSERT INTO `table_name` SET $final_string
ON DUPLICATE KEY UPDATE ($final_string)";

Agree that you should look at prepared statements, however to answer your original question you can do that like this:
$array=array('a', 'b', 'c');
$string = "'" . implode("','", $array) . "'";

Better use prepared queries. But just for funs sake:
implode(',', array_map(function($value) {
if(!is_numeric($value)) {
return '"' . $value . '"';
//adds double quotes, but if you prefer single quotes, use:
//return "'" . $value . "'";
} else {
return $value;
}
}, $array[0]);

The foreach+isnumeric() is probably the best approach. Then to change the value:
$array[$key] = "'" . $value . "'";
which turns foo/"foo" into 'foo'/"'foo'" and so on.

If you use the mysql-driver:
function escape( $x ) {
return "'" . mysql_real_escape_string($x) . "'";
}
$data = array( "1" => bar, "2" => foo, "3" => 13546 );
echo implode( ',', array_map('escape', $data) );

The verified solution didn't work for me. Must be something that i'm doing incorrectly, but the below solution worked for me and i used the result in my MYSQL IN clause since all the values needs to be in quoted form in that query.
The solution is simple and it uses call by reference to modify the original array values and array filter of PHP to loop through all the values.
function quote(&$a){
$a='"'.$a.'"';
}
$arr= array('car','bus','truck','bike');
array_filter( $arr,'quote');
echo implode(',', $arr);

Related

Remove single quote from just end of array element (String) in PHP

I have array of 3000 elements which are like this
Array[0]= 405adc92-cfad-4be6-9ad2-ca363eda4933
Array[1]= 405adc92-cfad-4be6-9ad2-ca363eda4933
And I need to pass a variable in a function which require only a single quote at the beginning. I tried a solution on web which is pasting single quote on beginning and end aswell .like this
function add_quotes($str) {
return sprintf("'%s'", $str);
}
$csv = implode(',', array_map('add_quotes', $a));
$myArray = explode(',', $csv);
echo gettype($myArray[1]);
so answer is like this
myArray[1]='405adc92-cfad-4be6-9ad2-ca363eda4933'
So what Could I do to get rid ?
could you not just add the ' at the beginning of each string, rather than first add too many of them and afterwards remove the wrongly placed?
foreach($myArray as $key => &$value) {
$value = "'" . $value;
}
or (may be more readable as not by-reference)
foreach($myArray as $key => $value) {
$myArray[$key] = "'" . $value;
}
You can use rtrim - http://uk1.php.net/manual/en/function.rtrim.php to achieve. The generic syntax is:
<?php
$foo = 'my string\'';
$bar = rtrim($foo, '\'');
var_dump($foo); //shows my string'
var_dump($bar); //shows my string
so in your case take the array values, then use rtrim($myArray['myKey'], '\'') - this should do it for you :)

PHP Postgresql using IN with pg_query_params

Can I pass values into this query? If so, what is the format of $arr?
$sql = "SELECT * FROM tree WHERE tree_id IN ($1);";
$result = pg_query_params($sql, [$arr]);
$sql = "SELECT * FROM tree WHERE tree_id = ANY ($1)";
$result2 = pg_query_params($sql2,[$arr]);
$arr format example = "{12,13}"
If your SQL statement contains an IN clause which takes a varying number of parameters, then it's somewhat tricky to use a parameterized query. As you've found out, you can solve this by using ANY instead of IN (documentation here), and then passing a PostgreSQL array as the sole query parameter.
$sql = 'SELECT * FROM tab WHERE id = ANY ($1);';
$id_array = [ 1, 2, 3 ]; // id_array can be of any size
$result = pg_query_params($sql, [ toPostgresArray($id_array) ]);
Whereby toPostgresArray() is the following helper function, which converts a PHP array into a PostgreSQL array:
function toPostgresArray($values) {
$strArray = [];
foreach ($values as $value) {
if (is_int($value) || is_float($value)) {
// For integers and floats, we can simply use strval().
$str = strval($value);
} else if (is_string($value)) {
// For strings, we must first do some text escaping.
$value = str_replace('\\', '\\\\', $value);
$value = str_replace('"', '\\"', $value);
$str = '"' . $value . '"';
} else if (is_bool($value)) {
// Convert the boolean value into a PostgreSQL constant.
$str = $value ? 'TRUE' : 'FALSE';
} else if (is_null($value)) {
// Convert the null value into a PostgreSQL constant.
$str = 'NULL';
} else {
throw new Exception('Unsupported data type encountered.');
}
$strArray[] = $str;
}
return '{' . implode(',', $strArray) . '}';
}

How to implode array with key and value without foreach in PHP

Without foreach,
how can I turn an array like this
array("item1"=>"object1", "item2"=>"object2",......."item-n"=>"object-n");
to a string like this
item1='object1', item2='object2',.... item-n='object-n'
I thought about implode() already, but it doesn't implode the key with it.
If foreach it necessary, is it possible to not nest the foreach?
EDIT: I've changed the string
EDIT2/UPDATE:
This question was asked quite a while ago. At that time, I wanted to write everything in one line so I would use ternary operators and nest built in function calls in favor of foreach. That was not a good practice! Write code that is readable, whether it is concise or not doesn't matter that much.
In this case: putting the foreach in a function will be much more readable and modular than writing a one-liner(Even though all the answers are great!).
You could use http_build_query, like this:
<?php
$a=array("item1"=>"object1", "item2"=>"object2");
echo http_build_query($a,'',', ');
?>
Output:
item1=object1, item2=object2
Demo
and another way:
$input = array(
'item1' => 'object1',
'item2' => 'object2',
'item-n' => 'object-n'
);
$output = implode(', ', array_map(
function ($v, $k) {
if(is_array($v)){
return $k.'[]='.implode('&'.$k.'[]=', $v);
}else{
return $k.'='.$v;
}
},
$input,
array_keys($input)
));
or:
$output = implode(', ', array_map(
function ($v, $k) { return sprintf("%s='%s'", $k, $v); },
$input,
array_keys($input)
));
I spent measurements (100000 iterations), what fastest way to glue an associative array?
Objective: To obtain a line of 1,000 items, in this format: "key:value,key2:value2"
We have array (for example):
$array = [
'test0' => 344,
'test1' => 235,
'test2' => 876,
...
];
Test number one:
Use http_build_query and str_replace:
str_replace('=', ':', http_build_query($array, null, ','));
Average time to implode 1000 elements: 0.00012930955084904
Test number two:
Use array_map and implode:
implode(',', array_map(
function ($v, $k) {
return $k.':'.$v;
},
$array,
array_keys($array)
));
Average time to implode 1000 elements: 0.0004890081976675
Test number three:
Use array_walk and implode:
array_walk($array,
function (&$v, $k) {
$v = $k.':'.$v;
}
);
implode(',', $array);
Average time to implode 1000 elements: 0.0003874126245348
Test number four:
Use foreach:
$str = '';
foreach($array as $key=>$item) {
$str .= $key.':'.$item.',';
}
rtrim($str, ',');
Average time to implode 1000 elements: 0.00026632803902445
I can conclude that the best way to glue the array - use http_build_query and str_replace
I would use serialize() or json_encode().
While it won't give your the exact result string you want, it would be much easier to encode/store/retrieve/decode later on.
Using array_walk
$a = array("item1"=>"object1", "item2"=>"object2","item-n"=>"object-n");
$r=array();
array_walk($a, create_function('$b, $c', 'global $r; $r[]="$c=$b";'));
echo implode(', ', $r);
IDEONE
You could use PHP's array_reduce as well,
$a = ['Name' => 'Last Name'];
function acc($acc,$k)use($a){ return $acc .= $k.":".$a[$k].",";}
$imploded = array_reduce(array_keys($a), "acc");
Change
- return substr($result, (-1 * strlen($glue)));
+ return substr($result, 0, -1 * strlen($glue));
if you want to resive the entire String without the last $glue
function key_implode(&$array, $glue) {
$result = "";
foreach ($array as $key => $value) {
$result .= $key . "=" . $value . $glue;
}
return substr($result, (-1 * strlen($glue)));
}
And the usage:
$str = key_implode($yourArray, ",");
For debugging purposes. Recursive write an array of nested arrays to a string.
Used foreach. Function stores National Language characters.
function q($input)
{
$glue = ', ';
$function = function ($v, $k) use (&$function, $glue) {
if (is_array($v)) {
$arr = [];
foreach ($v as $key => $value) {
$arr[] = $function($value, $key);
}
$result = "{" . implode($glue, $arr) . "}";
} else {
$result = sprintf("%s=\"%s\"", $k, var_export($v, true));
}
return $result;
};
return implode($glue, array_map($function, $input, array_keys($input))) . "\n";
}
Here is a simple example, using class:
$input = array(
'element1' => 'value1',
'element2' => 'value2',
'element3' => 'value3'
);
echo FlatData::flatArray($input,', ', '=');
class FlatData
{
public static function flatArray(array $input = array(), $separator_elements = ', ', $separator = ': ')
{
$output = implode($separator_elements, array_map(
function ($v, $k, $s) {
return sprintf("%s{$s}%s", $k, $v);
},
$input,
array_keys($input),
array_fill(0, count($input), $separator)
));
return $output;
}
}
For create mysql where conditions from array
$sWheres = array('item1' => 'object1',
'item2' => 'object2',
'item3' => 1,
'item4' => array(4,5),
'item5' => array('object3','object4'));
$sWhere = '';
if(!empty($sWheres)){
$sWhereConditions = array();
foreach ($sWheres as $key => $value){
if(!empty($value)){
if(is_array($value)){
$value = array_filter($value); // For remove blank values from array
if(!empty($value)){
array_walk($value, function(&$item){ $item = sprintf("'%s'", $item); }); // For make value string type 'string'
$sWhereConditions[] = sprintf("%s in (%s)", $key, implode(', ', $value));
}
}else{
$sWhereConditions[] = sprintf("%s='%s'", $key, $value);
}
}
}
if(!empty($sWhereConditions)){
$sWhere .= "(".implode(' AND ', $sWhereConditions).")";
}
}
echo $sWhere; // (item1='object1' AND item2='object2' AND item3='1' AND item4 in ('4', '5') AND item5 in ('object3', 'object4'))
Short one:
$string = implode('; ', array_map(fn($k, $v) => "$k=$v", array_keys($array), $array));
Using explode to get an array from any string is always OK, because array is an always in standard structure.
But about array to string, is there any reason to use predefined string in codes? while the string SHOULD be in any format to use!
The good point of foreach is that you can create the string AS YOU NEED IT!
I'd suggest still using foreach quiet readable and clean.
$list = array('a'=>'1', 'b'=>'2', 'c'=>'3');
$sql_val = array();
foreach ($list as $key => $value) {
$sql_val[] = "(" . $key . ", '" . $value . "') ";
}
$sql_val = implode(', ', $sql_val);
with results:
(a, '1') , (b, '2') , (c, '3')
|
(a: '1') , (b: '2') , (c: '3')
|
a:'1' , b:'2' , c:'3'
etc.
Also if the question is outdated and the solution not requested anymore, I just found myself in the need of printing an array for debugging purposes (throwing an exception and showing the array that caused the problem).
For this reason, I anyway propose my simple solution (one line, like originally asked):
$array = ['a very' => ['complex' => 'array']];
$imploded = var_export($array, true);
This will return the exported var instead of directly printing it on the screen and the var $imploded will contain the full export.

mysql_real_escape_string not being used with given regex

I am using a dataHandler library to handle all of my db inserts / updates, etc.
The library has the following functions:
function prepareValue($value, $connection){
$preparedValue = $value;
if(is_null($value)){
$preparedValue = 'NULL';
}
else{
$preparedValue = '\''.mysql_real_escape_string($value, $connection).'\'';
}
return $preparedValue;
}
function parseParams($params, $type, $connection){
$fields = "";
$values = "";
if ($type == "UPDATE"){
$return = "";
foreach ($params as $key => $value){
if ($return == ""){
if (preg_match("/\)$/", $value)){
$return = $key."=".$value;
}
else{
$return = $key."=".$this->prepareValue($value, $connection);
}
}
else{
if (preg_match("/\)$/", $value)){
$return = $return.", ".$key."=".$value;
}
else{
$return = $return.", ".$key."=".$this->prepareValue($value,
$connection);
}
}
}
return $return;
/* rest of function contains similar but for "INSERT", etc.
}
These functions are then used to build queries using sprintf, as in:
$query = sprintf("UPDATE table SET " .
$this->parseParams($params, "UPDATE", $conn) .
" WHERE fieldValue = %s;", $this->prepareValue($thesis_id, $conn));
$params is an associative array: array("db_field_name"=>$value, "db_field_name2"=>$value2, etc.)
I am now running into problems when I want to do an update or insert of a string that ends in ")" because the parseParams function does not put these values in quotes.
My question is this:
Why would this library NOT call prepareValue on strings that end in a closed parenthesis? Would calling mysql_real_escape_string() on this value cause any problems? I could easily modify the library, but I am assuming there is a reason the author handled this particular regex this way. I just can't figure out what that reason is! And I'm hesitant to make any modifications until I understand the reasoning behind what is here.
Thanks for your help!
Please note that inside prepareValue not only mysql_real_escape_string is applied to the value but it is also put inside '. With this in mind, we could suspect that author assumed all strings ending with ) to be mysql function calls, ie:
$params = array(
'field1' => "John Doe",
'field2' => "CONCAT('John',' ','Doe')",
'field3' => "NOW()"
);
Thats the only reasonable answer that comes to mind.

PHP array to jQuery options

I'm creating a Wordpress Plugin which uses a jQuery script. I've created a PHP array which contains its options like:
$settings = array('setting1' => 'value1', 'setting2' => 'value2', 'setting3' => 10)
I was now going to use foreach to loop over the items and print them like this:
foreach($settings as $setting => $value) {
if (is_string($value)) { $value = "'" . $value . "'"; }
$output .= $setting . ':' . $value .',';
}
which should make me end up with:
(window).load(function() {
$('#widget').myWidget({
setting1:'value1',
setting2:'value2',
setting3:10})
With the current setup I end up with the last entry having a ',' at the end (one too many) which means I get a Javascript error, so I need to remove it.
All with all, I have the feeling I'm doing something very dirty (including the is_string check) and I was wondering if there is a neat way to deal with this?
There is a json_encode function if you're using PHP >= 5.2
You should use json_encode() for this. It does all the dirty work for you.
(window).load(function() {
$('#widget').myWidget(
<?php echo json_encode($settings); ?>
);
}
Have you tried json_encode ?
Exemple from the docs:
<?php
$arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
echo json_encode($arr);
?>
Would output
{"a":1,"b":2,"c":3,"d":4,"e":5}
Here's a little thing I like to use when dealing with situations like this. I know it doesn't really answer your question, but it is an elegant way of solving the comma problem.
$comma = '';
foreach($settings as $setting => $value) {
if (is_string($value)) {
$value = "'" . $value . "'";
$output .= $comma . $setting . ':' . $value;
$comma = ',';
}
}
So on the first run $comma is blank, but after that it gets put between every new entry.

Categories