I got this code from google and it fulfills my requirement, but I don't understand the meaning of this line:
substr($query,0,strlen($query)-2)
Could somebody explain it to me?
<?php
function insert($tablename, $parameter_order, $values)
{
$query = "insert into $tablename (";
foreach($parameter_order as $po)
{
$query .= $po.', ';
}
$query = substr($query,0,strlen($query)-2).') values (';
foreach($values as $v)
{
$query .= "'$v', ";
}
$query = substr($query,0,strlen($query)-2).');';
return $this->makeQuery($query);
}
?>
This is what those functions do exactly:
substr() is used to generate a sub-string of specified length from another string.
strlen() will return the length of the provided string.
Code substr($query,0,strlen($query)-2) removes comma and space from foreach Loop.
The line removes the last comma and space from $query. These characters have been added in the foreach loop to glue together the elements of $parameter_order.
Note that this standard task is usually done better with the implode() function:
$query = "insert into $tablename (" . implode (', ', $parameter_order) . ' ) values (';
Related
I'm trying to make a function that creates a sql statement to insert data into a database and this is a snippet. It works fine except for the last foreach loop. For some reason it won't iterate to the last element in the array it'll stay stuck on the second last one. The issue is that the first foreach loop is the same code and it works fine, but the second is giving me trouble.
*note:The if statements in the foreach loops are supposed to catch the last element in the array and make sure that a ',' isn't inserted. And this is where the problem is. If I take the if statement out of the second loop the loop will iterate to the last element but without the if block it places a comma at the end and creates a SQL syntax error.
output of the first loop
INSERT INTO gardyloo.users (joe,bob,joe#hotmail.com,8de,154927,2014-12-18,2014-12-18 7:02:11)
output of second loop without if
VALUES (:firstName,:lastName,:emailAddress,:password,:userid,:date_joined,:timestamp,)
output of second loop with if
VALUES (:firstName,:lastName,:emailAddress,:password,:userid,:date_joined)
foreach( $values as $a => $b ){
if(next($values) == null){
$sql .= $b."";
break;
}
$sql .= $b.",";
}
$sql .= ") ";
$sql .= "VALUES (";
foreach( $values as $a => $b ){
if(next($values) == null){
$sql .= ":".$a;
break;
}
$sql .= ":".$a.",";
}
$sql .= ")";
*Edit, this code seems to work fine:
$sql .= implode(', ', array_keys($values));
$sql .= ") ";
$sql .= "VALUES (:";
$sql .= implode(", :", array_keys($values));
$sql .= ")";
Instead of break you need to use continue; Break interrupts the loop, while continue only move to next iteration.
Try this:
foreach( $values as $a => $b ){
if($b == null){
continue;
}
$sql .= ":".$a.",";
}
Do something like this:
//Your data
$values = array(
'firstName' => 'Joe',
'lastName' => 'bob',
'emailAddress' => 'joe#hotmail.com',
'password' => '8de',
'userid' => 154927,
'date_joined' => '2014-12-18',
'timestamp' => '2014-12-18 7:02:11'
);
//Begins the sentence
$sql = 'INSERT INTO gardyloo.users(';
/**
* Begins example code.
* - array_keys shows the key as a value
* example: $values[0] = firstName
*/
foreach(array_keys($values) as $k => $v)
{
//when the array arrives at the end, doesn't show ','
if($k != count($values)-1)
$sql .= $v.",";
else
$sql .= $v;
}
$sql .= ") ";
$sql .= "VALUES (";
$k = 0;//the new count initialized
foreach($values as $v)
{
//when the array arrives at the end, doesn't show ','
if($k != count($values)-1)
$sql .= $v.",";
else
$sql .= $v;
//increments the counter
$k++;
}
$sql .= ");";
Notes:
Separate the code in functions since both foreachs are very similar.
You can play with the foreach values to return the value that you want.
Ask me if you have more questions about it.
I'll do it otherwise. Instead of concat a string $sql create 2 variables, $columns and $values, both are arrays. And you don't need a loop to do this.
So here is how i would do it :
$columns = array_keys($values);
$sql = "INSERT INTO table (". implode(" ,", $columns) . ") VALUES (". implode(" ,", $values);
Here you don't need to test if it's the last element of the array to make a break;
Hope it helps ;)
The following code is supposed to check for the column names of a table. Then check to see if a corresponding variable has been $_POST and if it has add it to the $SQL. I believe there is a problem with the array that contains a series of arrays but I don't know how to dix it.
$where = $_POST['where'];
$is = $_POST['is'];
$table = $_POST['table'];
$sql = "UPDATE $table SET";
$array = array();
$columnnames = columnnames('blog');
foreach ($columnnames as $columnname){
if($_POST[$columnname]){
$sql .= " $columnname = :$columnname,";
$array .= array(':$columnname' => $_POST[$columnname],);
}
}
$sql = rtrim($sql,',');
$array = rtrim($array,',');
$sql .= " WHERE $where = '$is'";
$q = $rikdb->prepare($sql);
$q->execute($array);
For the sake of comprehension please except that $columnnames = columnnames('blog'); works as it does.
Change this:
$array .= array(':$columnname' => $_POST[$columnname],);
to this:
$array[':$columnname'] = $_POST[$columnname];
and after that use rtrim only on $sql.
the problem is here $array .= array(':$columnname' => $_POST[$columnname],);
you have a , part of the value which is not literal. change it to be like
$array .= array(':$columnname' => $_POST[$columnname] . ",");
You can also add your column names and values to an array and implode(",", $array) so you don't have to use rtrim
Instead of using
$array .= array(':$columnname' => $_POST[$columnname],);
and applying rtrim on results, I'd suggest the easier and failsafe method:
$array[':$columnname'] = $_POST[$columnname];
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
remove element from array based on its value?
I have this array
$arr = array(
'key1'=>'value1',
'key2'=>NULL,
'key3'=>'value2'
);
if I do implode(',',$arr); I get: value1,,value2 (notice the empty space)
Is there a way to skip that NULL values? To get something like this:
value1,value2
I could traverse all the array and unset manually the key where the value is NULL, but it's a bit an overkill doens't it?
Edit:
To save time Maybe I could do just one loop to iterate over the array, and in the same loop I check for null values and if isn't null I append it the ','
like this:
foreach($arr as $k=>$v) {
if ($v !== NULL) {
echo $v.',';
}
}
The problem here is that I have a final ',' at the end.
Edit
As gordon asked, it ran this test (1000000 iterations)
First using array_filter:
$pairsCache = array('key1'=>'value1','key2'=>NULL,'key3'=>'value3',
'key4'=>'value4','key5'=>'value5');
for($i=0;$i<1000000;$i++) {
$query = "INSERT INTO tbl (";
$keys='';
$values='';
$pairs = array_filter($pairsCache,function($v){return $v !== NULL;});
$keys = array_keys($pairs);
//> keys
$query .= implode(',',$keys ) . ") VALUES ( '";
//> values
$query .= implode("','",$pairs) . "')";
}
Time: 7.5949399471283
Query: "INSERT INTO tbl (key1,key3,key4,key5) VALUES ( 'value1','value3','value4','value5')"
Second using only one loop:
for($i=0;$i<1000000;$i++) {
$query = "INSERT INTO tbl (";
$keys='';
$values='';
foreach($pairsCache as $k=>$v) {
if ($v!==NULL) {
$keys .= $k.',';
$values .= "'{$v}',";
}
}
$keys=rtrim($keys,',');
$values=rtrim($values,',');
$query = $query . $keys . ') VALUES ( ' . $values . ')';
}
Time: 4.1640941333771
Query: INSERT INTO tbl (key1,key3,key4,key5,) VALUES ( 'value1','value3','value4','value5')
$arr = array_filter($arr);
array_filter() removes every value, that evaluates to false from $arr.
If you need finer control, you can pass a callback as second argument
arr = array_filter($arr, function ($item) { return !is_null($item);});
At last of course you can iterate over the array yourself
foreach (array_keys($arr) $key) {
if (is_null($arr[$key])) unset($arr[$key]);
}
Note, that there is no downside, if you filter and output in two separate steps
You can use array_filter():
If no callback is supplied, all entries of input equal to FALSE (see converting to boolean) will be removed.
implode(',', array_filter($arr));
There is no possibility to do this using only implode().
You can traverse all the array (as you said) maybe in a wrapper my_implode() function, or you can use something less elegant such as:
trim(preg_replace('/[,]+/', ',', implode(',', $arr)), ',');
You can simply use bellow code.
Edited.
function nullFilter($val)
{
return $val !== NULL;
}
$arr = array( 'key1'=>'value1', 'key2'=>NULL, 'key3'=>'value2' );
$filteredArray = array_filter($arr,"nullFilter");
echo implode(',', $filteredArray);
Cheers!
Prasad.
I'm trying to save some code with the following. I've an object with variables named the same as table rows so I could create an insert like this one:
$query = "INSERT INTO table ";
$columns = '(';
$values = 'VALUES (';
foreach ($this as $var => $value){
if ($value){
$columns .= $var.', ';
if (!is_int($value))
$value = '\''.$value.'\'';
$values .= $value.', ';
}
}
$columns .= ')';
$values .= ')';
$columns = str_replace (', )', ')', $columns);
$values = str_replace (', )', ')', $values);
$query .= $columns." ".$values;
But every single variable is detected as string and that's not true in all fields as you may imagine.
Does anyone have a solution?
Here's how I would write it:
<?php
$canonical_columns = array_flip(array("column1", "column2", "column3"));
$columns = array_keys(array_intersect_key($canonical_columns, (array) $this));
$params = join(",", array_fill(0, count($columns), "?"));
$columns = join(",", $columns);
$query = "INSERT INTO table ($columns) VALUES ($params)";
$stmt = $pdo->prepare($query);
$stmt->execute(array_values($this));
Stop concatenating fragments of strings to form SQL.
Use PDO, and use parameters for values.
Allowlist column names by comparing inputs to known, valid column names.
It appears as if you numbers are in fact strings. Try to use is_numeric() instead of is_int().
If this ain't enough you can cast the string to an integer and then check for != 0.
You may insert numbers in quotes too, as strings. This will not create an error.
So I have no idea what the deal is here... the following code below produces the mysql error following the code.
$fcontents = file("inventory.csv");
for ($i = 1; $i < sizeof($fcontents); $i++) {
$line = trim($fcontents[$i]);
$arr = explode(',', $line);
$values = implode(',', $arr);
$values = str_replace('&', 'and', $values);
$sql = 'INSERT INTO inventory (dealerid, name, vin, stock, newused, year, ' .
'make, model, series, body, color, intcolor, price, retailprice, ' .
'miles, transmission, engine, restraint, certified, photourl, ' .
'comments, flag, options, citympg, hwympg) ' .
'VALUES mysql_real_escape_string(' . $values . ')';
mysql_query($sql);
echo $sql.'<br><br>';
if (mysql_error()) {
echo mysql_error() .'<br><br>';
}
}
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '
RESOLVED!!! So I wanted to post the solution to the stupid, dumb single quote, double quote glitch when dumping a .csv file in mysql... See below.:
$fcontents = file("http://pathtofile.com/inventory.csv"); for($i=1; $i < sizeof($fcontents); $i++) { $line = trim($fcontents[$i]); $arr = explode(",", $line); $arr = str_replace ("'","'", $arr); $values = implode("','", $arr); $values = str_replace("\"',",'\'",', $values); $values = str_replace(",'\"",',"\'', $values); $values = str_replace("&", "and", $values); $sql = "INSERT INTO vehicles.inventory (dealerid,name,vin,stock,newused,year,make,model,series,body,color,intcolor,price,retailprice,miles,transmission,engine,restraint,certified,photourl,comments,flag,options,citympg,hwympg) VALUES ('".$values."')"; mysql_query($sql);
Between the explode() and implode() lines, you should be mysql_real_escape_string()-ing each of the values in $arr. The function should be executed in PHP, not sent to MySQL for it to execute.
You could have printed out (or logged) your generated SQL statement and you would probably have spotted the problem.
You have a PHP function in your MYSQL Query.
I don't believe you can just move the function outside of the quotes, but you have to loop through all values:
ie.
foreach($values as $key=>$value){
$values[$key] = mysql_real_escape_string($value);
}
Add that to escape all of the values, then change your query to remove the PHP function.
Also, you have to implode with quotes as well, not just commas.
mysql_real_escape_string() is a PHP function, but you're still within string scope when it appears in your code.
Try this:
$sql = 'INSERT INTO inventory (dealerid, name, vin, stock, newused, year, make, model, series, body, color, intcolor, price, retailprice, miles, transmission, engine, restraint, certified, photourl, comments, flag, options, citympg, hwympg) VALUES (' . mysql_real_escape_string($values) .')';