Okay, I don't know what exactly the problem is. So, I decided to post it here to discuss it with you.
The Problem is that, When I use php implode function in PDO execute(array(implode(",",$imploded)))); It doesn't work
When I use php implode function " the same function with the same variables " in the select statment, it works normally !
I've doubts that using it in the statment is a chance for SQL Injection.
Here's My Full Code :
$exCat = explode(",", $article['Category']);
$getCats = $con->prepare("SELECT * FROM `Categories` WHERE `ID` IN (?)");
if (is_array($exCat)) {
$getCats->execute(array(implode(",", $exCat))); /* This Is only displaying the first element */
} else {;
$getCats->execute(array($exCat));
}
$getCATS = $getCats->fetchAll();
This Works fine with me. However, I've doubts that using it in the statment is a chance for SQL Injection.
$exCat = explode(",", $article['Category']);
$anotherStmt = $con->prepare("SELECT * FROM `Categories` WHERE `ID` IN (" . implode(",", $exCat) . ")"); /* This Works fine */
$anotherStmt->execute();
$anotherCATS = $anotherStmt->fetchAll();
explode returns an array in every instance so is_array is not needed.
You need to use a placeholder for every value you want bound. I'd use str_repeat and rtrim to generate your placeholders then just pass the exploded array to the execute.
$exCat = explode(",", 'non commaed list, commaed');
$placeholders = rtrim(str_repeat('?,', count($exCat)), ', ');
$getCats = $con->prepare("SELECT * FROM `Categories` WHERE `ID` IN ({$placeholders})");
$getCats->execute($exCat);
Related
Given SQL-query with placeholders:
SELECT * FROM table WHERE `a`=? AND `b`=?
and query parameters ['aaa', 'bbb'], i would like to replace ?-placeholders with corresponding params. So, I do it like this:
$sql = preg_replace(array_fill(0, count($params), '#\?#'), $params, $sql, 1);
(we do not concentrate on mysql-escaping, quoting etc. in this question).
Everything works fine and I get
SELECT * FROM table WHERE `a`=aaa AND `b`=bbb
But if our first parameter looks like this: "?aa", everything fails:
SELECT * FROM table WHERE `a`=bbba AND `b`=?
obviously, first replacement pass changes "a=?" into "a=?aa", and second pass changes this (just inserted) question mark into "bbb".
The question is: how can I bypass this confusing preg_replace behaviour?
You can use preg_replace_callback to use one item from $params at a time for each replacement.
$sql = 'SELECT * FROM table WHERE `a`=? AND `b`=?';
var_dump('Original: ' . $sql);
$params=['aaa','bbb'];
$sql = preg_replace_callback("/\\?/",function($m) use (&$params) {
return array_shift($params);
}, $sql);
var_dump('Result: ' . $sql);
Let me know
I would not do this with preg_replace or str_replace. I would use preg_split so empty returns can be removed (If explode had empty removal option I'd use that). For there iterate over the return and add in values. You also can quote the values with this. I presume the purpose of this is for debugging parameterized queries.
$sql = 'SELECT * FROM table WHERE `a`=? AND `b`=?';
$v = array('1?1', "222");
$e = preg_split('/\?/', $sql, NULL, PREG_SPLIT_NO_EMPTY);
$c = '';
foreach($e as $k => $v1){
$c .= $v1 . "'" . $v[$k] ."'";
}
error_log($c);
Then your error log will have:
SELECT * FROM table WHERE `a`='1?1' AND `b`='222'
I have many conditions in PHP function which every of them produces a mysql query.All conditions work correctly except one query which ends with AND operator.Before returning the query result I need to check if query ends with AND it should remove AND and then returnes the query.
This is the sample of query:
$query="select * from case where case_name='name' AND case_status='102' AND";
If this kind of query is produced I need to do:
1-If it ends with AND
2-remove AND
3-return the query without last AND
The result should be like this:
$query="select * from case where case_name='name' AND case_status='102' ";
I do not have much experience to work with PHP functions.How can I do this?
Thnaks for your help.
Try this,
$query="select * from case where case_name='name' AND case_status='102' AND"
$query = trim($query,'AND');
quick fix:
$query = preg_replace( "/AND$/", "", $query);
You should fix the logic of condition though.
like
$cond[] = "....";
$cond[] = "...."
....
then
$query = $query_first_half + implode ( " AND " , $cond );
Ultimately please use sql library like PDO
http://fi1.php.net/manual/en/class.pdo.php
explode the string and pop the last element .
$arr = explode(" ", $query);
$last = array_pop($arr);
if($last != "and")
{
array_push($arr,$last);
}
$query = implode(" ",$arr);
Run the $query them it should work
First your table name CASE is mysql reserved keyword you should rename your table to something else or escpae it by backticks `
you could use query without AND , and when you add other query just start by AND .
like that :
$query="select * from `case` where case_name='name' AND case_status='102'";
$query .= " AND .........";
so like that , your condition is not true then just first query will work , if condition is true then second query will work and it start by AND. You dont need to remove the AND.
I have a file file.php and inside my file I am using the code bellow to pull some data from my database and display some information.
My code is
$array = $_GET['theurl']; // My url looks like myfile.php?theurl=1,2,3 (id,s)
$sqlnt4 = "select * from mytable WHERE `id` IN ($array)";
$rsdt4 = mysql_query($sql);
$tc4a = mysql_fetch_assoc($rsdt4);
$mycomma4 = ",";
if ($tc4a['a_youtube'] == "#"){
}else{
while ($tc4 = mysql_fetch_assoc($rsdt4))
{
echo $tc4['a_youtube'];
echo ",";
}
}
I expect to echo the infos of the two id's (in array) inside my while function, but it returns the results only from the first.
Any ideas?
I am confusing on $sql :
$sqlnt4 = "select * from mytable WHERE `id` IN ($array)";
$rsdt4 = mysql_query($sql);
Can you take a look after changing below:
$sqlnt4 = "select * from mytable WHERE `id` IN ($array)";
$rsdt4 = mysql_query($sqlnt4);
First that's extremely vulnerable to security issues - I hope this isn't used in production and just for playing around.
I recommend switching to PDO, or at the very least securing your variables.
To put that array into the query, you need to implode it into a list, as such.
$list = implode(',', $array);
You can then use the list in the statement, which will look like 1,2,3.
Edit:
I've just realized your $array value isn't actually an array - have you missed code out or is it badly named?
mysql_fetch_assoc: "Returns an associative array that corresponds to the fetched row and moves the internal data pointer ahead." http://pt2.php.net/mysql_fetch_assoc
Try mysql_fetch_rows to return all matching rows into an array.
I ran into the following question while writing a PHP script. I need to store the first two integers from an array of variable lenght into a database table, remove them and repeat this until the array is empty. I could do it with a while loop, but I read that you should avoid writing SQL statements inside a loop because of the performance hit.
A simpliefied example:
while(count($array) > 0){
if ($sql = $db_connect->prepare("INSERT INTO table (number1, number2) VALUES (?,?)")){
$sql->bind_param('ii',$array[0],$array[1]);
$sql->execute();
$sql->close();
}
array_shift($array);
array_shift($array);
}
Is this the best way, and if not, what's a better approach?
You can do something like this, which is way faster aswell:
Psuedo code:
$stack = array();
while(count($array) > 0){
array_push($stack, "(" . $array[0] . ", " . $array[1] . ")");
array_shift($array);
array_shift($array);
}
if ($sql = $db_connect->prepare("INSERT INTO table (number1, number2)
VALUES " . implode(',', $stack))){
$sql->execute();
$sql->close();
}
The only issue here is that it's not a "MySQL Safe" insert, you will need to fix that!
This will generate and Array that holds the values. Within 1 query it will insert all values at once, where you need less MySQL time.
Whether you run them one by one or in an array, an INSERT statement is not going to make a noticeable performance hit, from my experience.
The database connection is only opened once, so it is not a huge issue. I guess if you are doing some insane amount of queries, it could be.
I think as long as your loop condition is safe ( will break in time ) and you got something from it .. it's ok
You would be better off writing a bulk insert statement, less hits on mysql
$sql = "INSERT INTO table(number1, number2) VALUES";
$params = array();
foreach( $array as $item ) {
$sql .= "(?,?),\n";
$params[] = $item;
}
$sql = rtrim( $sql, ",\n" ) . ';';
$sql = $db_connect->prepare( $sql );
foreach( $params as $param ) {
$sql->bind_param( 'ii', $param[ 0 ], $param[ 1 ] );
}
$sql->execute();
$sql->close();
In ColdFusion you can put your loop inside the query instead of the other way around. I'm not a php programmer but my general belief is that most things that can be done in language a can also be done in language b. This code shows the concept. You should be able to figure out a php version.
<cfquery>
insert into mytable
(field1, field2)
select null, null
from SomeSmallTable
where 1=2
<cfloop from="1' to="#arrayLen(myArray)#" index="i">
select <cfqueryparam value="myArray[i][1]
, <cfqueryparam value="myArray[i][]
from SomeSmallTable
</cfloop>
</cfquery>
When I've looked at this approach myself, I've found it to be faster than query inside loop with oracle and sql server. I found it to be slower with redbrick.
There is a limitation with this approach. Sql server has a maximum number of parameters it will accept and a maximum query length. Other db engines might as well, I've just not discovered them yet.
Apologies for the newbishness of this question. I'm just starting a project and I have an array of IDs to grab certain records from a table. What's the best way to go about this?
Will the following work?
public function getWork($slideIDs) {
$params = array();
$params = $slideIDs;
$count = count($params);
for($i=0;$i<$count;$i++) {
$STH = $this->_db->prepare("SELECT *
FROM slides
WHERE slideID = :slideID;");
$STH->execute($params[$i]);
}
$result = $STH->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
Thanks.
Better to execute just one SQL statement using an IN clause
SELECT * FROM slides WHERE slideID IN (1,2,3,4,5, ...)
Since fewer connections and trips to the database is generally better for performance.
So just build that SQL string in your loop, then move the Execute to the bottom (outside your loop.)
Adjust your PHP to create a single query string with this format:
SELECT *
FROM slides
WHERE slideID IN (2,5,11)
Do not execute multiple queries. :)
Same as others ;)
Use implode($array, ",") to get the part which should go into the IN() statement
The following should work. Used implode to create the required string containing the IDs separated by comma to pass to SQL.
function getWork($slideIDs) {
$params = implode(",",$slideIDs);
$STH = $this->_db->prepare("SELECT *
FROM slides
WHERE slideID in ( :slideID );");
$STH->execute($params);
$result = $STH->fetchAll(PDO::FETCH_ASSOC);
return $result;
}