I am looking to use the contents of an array
$arr =array(24,28,30,34, 40);
and pass these into the where clause of a MySQL select statement, all my research has shown this done by using IN to pass in all the array values in one go.
I need to pass in each array element one at a time and then echo out the results of the SQL statement one at a time as the select statement is updated with the next array element.
New to programming and PHP so just need a little example to get me started...
Thanks to Zad highlighted the real issue
I need to pass each array value individually to a SQL statement as these need to be utilised in Where clause with BETWEEN, eg. WHERE age BETWEEN $array1 AND $array2 in order to determine count over an age range
thanks for all the input
You can use the implode function to build the string that contains the list;
$arr =array(24,28,30,34, 40);
$query = 'SELECT * FROM mytable WHERE id IN (' .implode($arr, ', '). ' )';
echo $query;`
http://codepad.org/tLPZxq8P
http://mx2.php.net/manual/en/function.implode.php
try it with escaping the argument
foreach($arr as $array_element) {
$query = 'SELECT * FROM table WHERE field = \''.mysql_real_escape_string($array_element).'\'';
//your statement
}
You can use a foreach function:
// make connection to mysql server
foreach ( $arr as $element ) {
$statement = "SELECT whatever FROM wherever WHERE something = $element"; // maybe a little validation here wouldn't hurt either
// execute statement
// process results
} // end of foreach
// close connection
$arr =array(24,28,30,34, 40);
$a = 'SELECT * FROM foo WHERE bar IN('.implode(',',$arr).')';
Edit: I'll admit, I didn't fully read the question, the title is misleading - consider changing that.
I need to pass in each array element one at a time and then echo out
the results of the SQL statement one at a time as the select statement
is updated with the next array element.
Could you explain how the scenario a bit better?
Related
The intention with the below code is to extract messages from a mysql table, and put each of them inside ONE array with {} around each output. Each output consists of various parameters as you can see, and is an array in itself.
What the code does is that each time the loop is processed, in the JSON array that this later is converted into, it wraps the output in []´s, hence it´s now a new array which is created.
What I get is:
[{"sender":"ll","message":"blah","timestamp":"2016-12-21 14:43:04","username":"","msgtype":"","threadid":"32629016712222016034323"},{"sender":"kk","message":"blahblah","timestamp":"2016-12-21 14:43:23","username":"","msgtype":"","threadid":"32629016712222016034323"},{"sender":"ll","message":"blahblahblah","timestamp":"2016-12-21 14:43:47","username":"","msgtype":"","threadid":"32629016712222016034323"}],[{"sender":"ll","message":"blahblahblahblah","timestamp":"2016-12-21 14:43:04","username":"","msgtype":"","threadid":"92337321312222016034304"},{"sender":"kk","message":"blahblahblahblahblah","timestamp":"2016-12-21 14:44:05","username":"","msgtype":"","threadid":"92337321312222016034304"}]]
And what I want is:
[{"sender":"ll","message":"blah","timestamp":"2016-12-21 14:43:04","username":"","msgtype":"","threadid":"32629016712222016034323"},{"sender":"kk","message":"blahblah","timestamp":"2016-12-21 14:43:23","username":"","msgtype":"","threadid":"32629016712222016034323"},{"sender":"ll","message":"blahblahblah","timestamp":"2016-12-21 14:43:47","username":"","msgtype":"","threadid":"32629016712222016034323"}],{"sender":"ll","message":"blahblahblahblah","timestamp":"2016-12-21 14:43:04","username":"","msgtype":"","threadid":"92337321312222016034304"},{"sender":"kk","message":"blahblahblahblahblah","timestamp":"2016-12-21 14:44:05","username":"","msgtype":"","threadid":"92337321312222016034304"}]
How do I proceed to get the right result here?
$data = array ();
foreach($threads as $threadid){
$sql = ("SELECT sender,message,timestamp,username,msgtype,threadid FROM Messages WHERE threadid = '$threadid' AND subject = '' AND timestamp > '$newtimestamp' ORDER BY timestamp");
$arrayOfObjects = $conn->query($sql)->fetchAll(PDO::FETCH_OBJ);
$data[] = $$arrayOfObjects;
}
And FYI, $threadid is another array containing... threadids, and the loop correctly fetches these one by one, that´s not where the problem is.
Thanks in advance!!
You are doing O(N) database queries, consider doing just O(1) using an IN expression in your where clause. No need for a foreach loop and you'll get all your data in one array.
SELECT ... FROM Messages WHERE threadid IN (1, 2, 3, ...) AND ...
You might have to use a prepared statement for that.
I think you are searching for PDO::FETCH_OBJ.
You had FETCH_ASSOC, which will return an array of associative arrays.
FETCH_OBJwill return an array ob stdObjects.
Also you reassigned $array to itself when doing $array[] = $array;..
$data = array();
foreach($threads as $threadid){
$sql = ("SELECT sender,message,timestamp,username,msgtype,threadid FROM Messages WHERE threadid = '$threadid' AND subject = '' AND timestamp > '$newtimestamp' ORDER BY timestamp");
// here it is:
$arrayOfObjects = $conn->query($sql)->fetchAll(PDO::FETCH_OBJ);
$data[] = $arrayOfObjects;
}
// now you can encode that as json and show it:
echo json_encode($data);
#akuhn
Well, I decided to give your suggestion one more try, and managed to do it in a none prepared way. I´m aware that this is supposed to be risky, but so far this project just needs to work, then have the php codes updated to safer versions, and then go live. It works, so thanks a bunch!
$sql = ("SELECT sender,message,timestamp,username,msgtype,threadid FROM Messages WHERE threadid IN ('" . implode("','",$threadid) . "') AND subject = '' AND timestamp > '$newtimestamp' ORDER BY timestamp");
$data = $conn->query($sql)->fetchAll(PDO::FETCH_OBJ);
I'm running a PDO query, something like:
$inputArr = array(val1, val2, val3, ...);
$qMarks = str_repeat('?,', count($inputArr) - 1) . '?';
$stmt = $db->prepare("SELECT id, name, type, level
FROM table
WHERE name IN ($qMarks)");
$stmt->execute($inputArr);
... parse the rows that have been returned
And this works exactly as expected, no hang-ups or anything.
My problem is that I need to know which value from $inputArr was used to get each row returned.
I've tried
WHERE name IN ($qMarks) AS inputVal
and
WHERE name IN ($qMarks AS inputVal)
but those crash the query.
How can I determine which input array value was used to return each row in the output?
EDIT 1
Yes, I understand that the input search value would be name, for this particular case, but the query above is only for demonstration purposes of how I am putting the search values into the query.
The actual is much more complex, and returns any name value with is close (but not always identical).
The AS keyword is not going to work as you expect it. It's mainly used for aliasing subqueries. You can't (to my knowledge) use it in a WHERE clause.
The scenario you've outlined should have the 'name' in $row['name']. If it was a different variable that you wanted to see, you'd simply add it in your SELECT clause.
Great question, and simple answer:
The WHERE name IN $qMarks)"); part of your code is only obtaining the values in your database that are matching your array, so what you can do is see which values of name are present in the row you fetched. For example:
$rows_fetched = $stmt->fetchAll(PDO::FETCHASSOC);
$inputArray = array();
foreach($rows_fetched as $value)
{
$inputArray[] = $value['name'];
}
print_r($inputArray);//printing the results
Now you have the array $inputArray with all the values used to return each row in the output. Let me know if that worked for you!
I'm trying to figure out the best possible way to build this. Here's what I have so far:
Sum up all the widgets sold in a single zip code:
select `Widgets`, SUM(`number sold`) as total_sold from mytable where
`Widgets`="Super Widget" and `zip_code`="35801"
So far, so good. I can do something similar if I want sales from two zip codes:
select `Widgets`, SUM(`number sold`) as total_sold from mytable where
`Widgets`="Super Widget" and (`zip_code`="35801" or
`zip_code`="12345")
Works great.
What I need to do is be able to set this up such that the user can select multiple zip codes without knowing in advance how many they want. Could be 2 or 20. Is there a way to structure this query as an array or similar? Pseudo-code:
select `Widgets`, SUM(`number sold`) as total_sold from mytable where
`Widgets`="Super Widget" and
(`zip_code`=in_array[35801,12345,00124,43562,12441])
This would show all the sales in these 5 zip codes. This would be a simple query to build by getting user input on the front end as a comma separated input.
Any suggestions would be appreciated.
Use in
select `Widgets`, SUM(`number sold`) as total_sold from mytable where `Widgets`="Super Widget" and `zip_code` in (35801,12345,00124,43562,12441)
You can use the IN function (here's an example from the link):
SELECT 'wefwf' IN ('wee','wefwf','weg');
Applied to your situation, it might look like:
...
and (`zip_code` IN ('35801', '12345', '00124', '43562', '12441'))
As mentioned, you can use IN function of SQL, and if you are building this query in PHP code (you added a php tag), then you can use implode function to create the "in array".
$arr = ['a', 'b', 'c'];
$line = implode(',', $arr);
echo $line; // Will output: a,b,c
Notice that writing the values directly to the query string is very dangerous, as it will expose your application to SQL injection attacks.
UPDATE:
You can use IN with PDO, with a little workaround - you can create question mark place holder in the query for each one of the values.
We will use str_repeat function to create the required question mark place holders, and rtrim function to remove the last comma.
Assuming your list of values is stored in $arr and your PDO reference is in $pdo:
$arr = ['value 1', 'value 2', 'value 3' ...];
$placeHolders = rtrim(str_repeat('?,', cound($arr)), ',');
$query = "SELECT * FROM table WHERE id IN ($placeHolders)";
$stmt = $pdo->prepare($query);
$stmt->execute($arr);
The variable $placeHolders will hold a string with '?' place holders for parameters, in the amount of the number of elements in the array, and then you can pass the array to the execute function of the prepeared statement.
Following is my code showing some error in mysql query:
<?php
$con=mysql_connect('localhost','root','');
$str=$_GET["message"];
$stor=explode(" ",$str);// converting message into array
mysql_select_db('words',$con);
for($j=0;$j<=30; $j++)
{
mysql_query($con,"UPDATE blacklist SET $stor=1 where $stor=0");//if column name=element in array then make it as 1 in database
}
mysql_close($con);
?>
Your code is vulnerable to SQL Injection. Read up on prepared statements and use PDO/MySQLi.
$stor is an array object and cant be used directly in the query. If you want to use it, try using
IN('.implode(",", $stor).')
the code above does the following:
implode() - takes an array and turns it into a comma separated string.
IN() - compares the given comma separated values and returns true if at least one of them exists.
Example (implode):
implode(",", array(1,2,3)) IS EQUAL TO "1,2,3"
Example (IN):
TestID IN (1,2,3) IS SAME AS (TestID = 1 OR TestID = 2 OR TestID = 3)
You're probably getting a mysql error because your query ends up looking like this
UPDATE blacklist SET Array=1 where Array=0;
If you're just echoing out a full array, you get Array instead, you'll need to specify an array element ($stor[1] for example).
What you'll want to do is replace your for loop with a foreach so that you can just throw out the elements one at a time.
Also, your arguments are backwards.
foreach($stor as $word)
{
mysql_query("UPDATE blacklist SET $word=1 where $word=0", $con);
}
When the user check more than one (checkbox) option which are then combine into a string of "apple,orange,pear"
SELECT id, pos, FROM $db WHERE dtime>='$now' AND jsub IN ('$arr[1]') ;
When I pass the string to $arr[1], it won't work correctly, how do I split into array and get mysql IN function to process correctly?
use:
$str = "SELECT id, pos, FROM $db
WHERE dtime>='$now' AND jsub IN ('".explode(',',$arr."')";
and don't forget to sanitize the parameters before ...
Use FIND_IN_SET.
SELECT id, pos, FROM $db WHERE dtime>='$now' AND FIND_IN_SET(jsub, '$arr[1]')
the question is WAY unclear, but I suspect you want something like
foreach ($arr as $key => $item) $arr[$key] = mysql_real_escape_string($item);
$in = "'".implode("','",$arr);
$sql = "SELECT id, pos, FROM $db WHERE dtime>='$now' AND jsub IN ($in)";
But man, I hate guessing.
Why don't you get yourself a static query, without any PHP code?
To see, if it ever works?
If not - ask on SO for the proper query. SQL query, not PHP code.
If yes - write a PHP code that produces the exact query.
Compare to the example one.
If failed - ask on SO for the PHP code, providing an example of the resulting query and an array.
Is it too hard rules to follow?