SQL IN not working when ran from php [duplicate] - php

This question already has answers here:
Can I bind an array to an IN() condition in a PDO query?
(23 answers)
MySQLi Bind Param with an array for IN [duplicate]
(2 answers)
Closed 9 years ago.
I'm trying to write code that basically finds your facebook friends that are on my website. I succeed in phpmyadmin running the query but for some reason when i try to run the code from php it doesn't work
Here's the php code. Whenever i take the $string echo and place it in mysql it works just fine, but for whatever reason when running it in php the query is not returning any results.
$fql = "SELECT uid FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = 100000903067831) AND is_app_user = 'true'";
$param = array(
'method' => 'fql.query',
'query' => $fql
);
$this->load->library('facebook');
echo $this->facebook->getLoginUrl();
$fqlResult = $this->facebook->api($param);
$userIDarray = array();
foreach($fqlResult as $result)
{
echo $result['uid']."<br>";
array_push($userIDarray, intval($result['uid']));
}
$string = implode(', ',$userIDarray);
echo $string;
$vars = array($string);
$query = $this->db->query("SELECT * FROM users WHERE users.facebook_id IN (?)", $vars);
echo var_dump($query);
foreach($query->result() as $data)
{
echo var_dump($data);
}

You cannot pass multiple parameters in a single ?.
You need to construct the options for IN yourself using concatenation.
Like so:
foreach($fqlResult as $result)
{
echo $result['uid']."<br>";
array_push($userIDarray, intval($result['uid']));
}
$string = implode(', ',$userIDarray);
$query = $this->db->query("SELECT * FROM users WHERE users.facebook_id
IN ('.$string.')");
Note that you need to make sure your items in the $userIDarray are properly escaped.
Because you're not using parameters, but you've injected these values into your SQL you are in danger of SQL injection attacks.
You are passing them through intval which guarantees that the strings will only contain 0..9 and - so you are safe from that here.
If the data is not numeric, you need use mysqli_real_escape_string to compensate for the fact that you're bypassing PDO's parameters.

Related

Using str_replace in table query in MYSQL [duplicate]

This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
If you create a variable inside a if statement is it available outside the if statement?
(4 answers)
How to replace "if" statement with a ternary operator ( ? : )?
(16 answers)
If variable equals value php [duplicate]
(4 answers)
Closed 2 years ago.
There are a lot of examples on SO of using str_replace to modify a query that uses variables in MYSQL but I can't find one that solves my problem.
I have the following legacy query that I'm debugging written in PHP and MySQL.
Somewhat simplified it is:
$sql = "SELECT * from MOVIES WHERE cat = '$cat'";
In the event that cat has a certain value, say, "action" I want to check for "adventure";
Let's say you start with query:
$cat = "action";
$sql = "SELECT * FROM MOVIES WHERE cat='$cat'";
I'm trying to modify the query with:
$needle = "cat=".$cat;
$altcat = "adventure";
$altwhere = "cat=".altcat;
$sql = str_replace($needle,$altwhere,$sql); //NOTHING GETS REPLACED...NOT MATCHING Needle
How can I do this? I'm thinking the problem has something to do with use of spaces or apostrophes in the sql string but can't get it to work.
Thanks for any suggestions.
You want to replace "cat='".$cat."'" with "cat='adventure'", not "cat=".$cat with "cat=adventure".
(Though you are inconsistent in saying if there are spaces around the =.)
But you should not do this and should use a placeholder instead.
I would not try to do string substitution on the SQL query. Instead, just use query parameters.
$cat = 'action'; // suppose this is the input to your program
$sql = "SELECT * from MOVIES WHERE cat = ?";
if ($cat == 'action') {
$cat = 'adventure';
}
$stmt = $db->prepare($sql);
$stmt->execute( [ $cat ] );

Is there a solution to "object of class mysqli_result could not be converted to string"? [duplicate]

This question already has answers here:
Object of class mysqli_result could not be converted to string
(5 answers)
Closed 1 year ago.
I searched the Internet for some Solutions but none of it works and I can't find out why. I'm new to PHP and MYSQL/MyAdmin so I really don't understand what I did wrong.
I've already tried several commands and "while $row = $result->fetch_array()" and stuff like that.
$Word = "SELECT Word FROM RandWord WHERE Number = '$Number'";
$Word = mysqli_query($data, $Word);
echo $Word;
$Amount = count($Word);
I want it to Output the "Count($Word);" for me, but it can't even echo because it can not be converted into a string. I want to see the word and use it.
You need to actually fetch the results first, before you can use it. You are also vulnerable to SQL injection attacks, so use a prepared statement instead.
In your code $Word is a result-object, which holds information - but you need to use a fetching method to retrieve the data first. count() in PHP is only usable on arrays (or on objects, but not that object which you get from mysqli_query()).
$query = "SELECT Word FROM RandWord WHERE Number = ?";
$stmt = $data->prepare($query);
$stmt->bind_param("s", $Number);
$stmt->execute();
$stmt->bind_result($word);
while ($stmt->fetch()) {
echo $word;
}
$stmt->close();
If you want it to be a count of each word, you have to run a query using the MySQL function COUNT() instead.
$query = "SELECT Word, COUNT(Word) as cnt FROM RandWord WHERE Number = ? GROUP BY Word";
$stmt = $data->prepare($query);
$stmt->bind_param("s", $Number);
$stmt->execute();
$stmt->bind_result($word, $count);
while ($stmt->fetch()) {
echo $word." has count ".$count;
}
$stmt->close();

Dynamic select mysqli query with dynamic parameters returns error doesn't match number of bind variables [duplicate]

This question already has answers here:
Use an array in a mysqli prepared statement: `WHERE .. IN(..)` query [duplicate]
(8 answers)
Closed 11 months ago.
I'm trying to create a select query with dynamic where clause and dynamic parameters but I always get error :
Warning: mysqli_stmt::bind_param(): Number of elements in type
definition string doesn't match number of bind variables
Which I sincerely do not understand since it seems the count is alright. So this is what the code really looks like in its rude format. I can't see what I'm doing wrong.
//get variables
$mediaArray ='Facebook,Twitter,Twitch,';
$otherMedia = 'House';
//convert string to array
$socialArray = explode(',', $mediaArray)
//declare some variables to be used later
$andwhere = '';
$bp = '';
$socialmarray = ''
//get every value from array of social media
foreach($socialArray as $socialmedia){
$socialmarray .=$socialmedia.',';
$andwhere .= " AND socialmedianame=?";
$bp .='s';
}
//test strings
echo $wheres = $andwhere;//AND socialmedianame=? AND socialmedianame=? AND socialmedianame=?
echo $bip = $bp.'s';//ssss
echo $validarayy = rtrim($socialmarray,',');//Facebook,Twitter,Twitch
//select query
$selectquery = $conn->prepare("select * from mediaservices where socialmedianame=? $wheres");
$selectquery->bind_param("$bip",$otherMedia,$validarayy);
$selectquery->execute();
$resultquery = $selectquery->get_result();
Because:
You are using user-supplied data, you must assume that your query is vulnerable to a malicious injection attack and
the amount of data that is to be built into the query is variable/indefinite and
you are only writing conditional checks on a single table column
You should use a prepared statement and merge all of the WHERE clause logic into a single IN statement.
Building this dynamic prepared statement is more convoluted (in terms of syntax) than using pdo, but it doesn't mean that you need to abandon mysqli simply because of this task.
$mediaArray ='Facebook,Twitter,Twitch,';
$otherMedia = 'House';
$media = array_unique(explode(',', $mediaArray . $otherMedia));
$count = count($media);
$conn = new mysqli("localhost", "root", "", "myDB");
$sql = "SELECT * FROM mediaservices";
if ($count) {
$stmt = $conn->prepare("$sql WHERE socialmedianame IN (" . implode(',', array_fill(0, $count, '?')) . ")");
$stmt->bind_param(str_repeat('s', $count), ...$media);
$stmt->execute();
$result = $stmt->get_result();
} else {
$result = $conn->query($sql);
}
foreach ($result as $row) {
// access values like $row['socialmedianame']
}
For anyone looking for similar dynamic querying techniques:
SELECT with dynamic number of LIKE conditions
INSERT dynamic number of rows with one execute() call
In your query:
$selectquery = $conn->prepare("select * from mediaservices where socialmedianame=? $wheres");
The ? represents one parameter to pass in, and the evaluation of $wheres adds another three, giving you four total parameters.
bind_param() should take a string representing the types of the variables to insert as the first parameter, and the variables themselves as the subsequent parameters.
In your bind:
$selectquery->bind_param("$bip",$otherMedia,$validarayy);
$bip evaluates to ssss and $otherMedia is a single string ("House"). You might expect $validarayy to be three strings, but rtrim() returns a string. Thus, it is only one string ("Facebook,Twitter,Twitch"). You pass through two variables when the query is expecting four:
$conn->prepare("select * from mediaservices where socialmedianame=House AND socialmedianame=Facebook,Twitter,Twitch AND socialmedianame=? AND socialmedianame=? AND socialmedianame=?"
To correct this, you'll want to convert $validarayy back to an array, and use the index for the various inputs:
$socialmarray2 = explode(',', $validarayy);
$selectquery->bind_param("$bip", $otherMedia, $socialmarray2[0], $socialmarray2[1], $socialmarray2[2]);
Also note that your sample code has a few missing semicolons; you'll need to fix these in order for your code to work correctly.
This can be seen working here.
Finally, note that even if you were to split the three strings out correctly, the selection of ... AND socialmedianame=Facebook AND socialmedianame=Twitter AND socialmedianame=Twitch will never match any results; socialmedianame can only contain one value. You're probably looking to substitute your AND statements with OR statements.

Am I doing the mysqli right? [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 8 years ago.
Every question which I asked on stackoverflow I received a question that It was easy to do a php injection into my script.
I've now a example and checked some tutorials on youtube.
Am I doing this right now?
This is an example how I'm working now
if($user->isLoggedIn()) {
$pakuser = $user->data()->username;
$sql = $db->query("SELECT * FROM users
INNER JOIN post ON users.username = post.add
WHERE post.id = $id AND post.add = '$pakuser'")
or die(mysql_error());
if ($sql === FALSE) {
}
if($row = $sql->fetch_object())
if($row->add)
{
?>
<p>edit this post<br><br>BEWARE OF DELETING YOUR CONTENT THERE IS NO GO-BACK<BR>Delete this post </p>
<?php
}
}
Everytime the user can manipulate your sql-query without any restriction, there is a security-issue. Here is an example:
$query_string = "SELECT * FROM user WHERE (name='$username' AND password='$password')";
if the user sends a password like:
"something') OR ('1' = '1"
the query will change to:
$query_string = "SELECT * FROM user WHERE (name='Name' AND password='something') OR ('1' = '1')";
Because '1'='1' is always true, this will return each user in your database.
Instead you can change the example above to:
$query = mysqli->prepare('SELECT * FROM user WHERE (name=? AND password=?)');
$query->bind_param('ss', $username, $password);
$query->execute();
This will filter all strings that could break your sql-query.
It seems like you are still just passing variables straight through into the query. Yes, this may work, but is not necessary secure.
You could have a look at using PDO instead, which has means of being able to verify the data type that you are wanting to pass through into your query rather than just passing a variable into the query string.
In terms of using mysqli, have a look at mysqli_real_escape_string if you have not already. It is well documented.

In zend, how to print a mysql query properly? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to print exact sql query in zend framework ?
In zend profiler, I can only either print the query with question markers (getQuery) or print the parameter array (getQueryParams).
Is there a way to replace all question markers, and print the real sql query?
Thanks!
Something like that should work:
$profile = $this->getQueryProfile($queryId);
$query = $profile->getQuery();
$params = $profile->getQueryParams();
foreach ($params as $par) {
$query = preg_replace('/\\?/', "'" . $par . "'", $query, 1);
}
The framework uses prepared statements so actually this is the real query - in reality its send to the database which parses it and then the params are binded to it and executed.
You can use the __toString() method.
$dbTable = new Application_Model_DbTable_TradeshowBooking();
$select = $dbTable->select();
$select->setIntegrityCheck(false);
$select->where('ends_on + INTERVAL 4 WEEK > ? ', $requestParams['ends_on']);
Zend_Registry::get('logger')->log($select->__toString(), Zend_Log::INFO);

Categories