how to transform a function from mysql into mysqli - php

hello i would like to transform a mysql-function into a mysqli version. this function is for checking if an user exists or not. so i'm new to functions and even to mysqli. thats why i'm having problems while transforming it.
the mysql-version is:
function a($uname){
return (mysql_result(mysql_query("SELECT COUNT (`a`) FROM `table_1` WHERE `a`='$uname'"), 0) == 1) ? true : false;
}
the mysqli-version i thought would be:
function a($uname){
return (mysqli_num_rows(mysqli->query("SELECT COUNT (`a`) FROM `table_1` WHERE `a`='$uname'"), 0) == 1) ? true : false;
}
i know that there is no mysql_result anymore. i decided to use mysqli_num_rows. but this function does not work and i have no clue why. error_reporting is enabled but when calling the page, i will get a blank page with no error messages?!
so if there is someone who could help me out i really would appreciate.
thanks alot.

You need a helper function to put all dirty mysqli internals behind the scenes.
Like safemysql. It can mimic mysql_result as well:
function a($uname){
global $db; // with mysqi you have to connect once and then use this connection
return (bool)$db->getOne("SELECT COUNT (1) FROM table_1 WHERE a=?s"), $uname);
}
and can solve dozens of similar issues.

Freely from the documentation:
mysqli->query returns either a mysqli_result object for queries, which actually return some results, 'false' for failed queries and 'true' for all other queries (if successful).
You will not know anything about the result of your query, unless you check the result more thoroughly.
Try something like this: (This assumes that the connection has been successfully established, and that $uname has been properly escaped.)
function a($uname) {
$found = false;
$result = mysqli->query("SELECT `a` FROM `table_1` WHERE `a`='$uname'");
if($result) {
//We used a 'SELECT' query and the query was successful. That means, we now have a mysqli_result object.
$found = ($result->num_rows == 1); //Determines, if something was actually found or not.
$result->close(); //Frees some ressources. Not necessary, but doesn't hurt either.
} else { //The query failed, as such we have nothing to evaluate.
die("Queryerror: ".mysqli->error);
}
return $found;
}
I changed the query parameter from 'COUNT' to 'a', because otherwise 'num_rows' will ALWAYS return 1, even if the actual count is '0'. This way, it returns the number of matched rows, essentially return '0' for 'no match' or '1' for 'match'.

Related

In PHP, why doesn't mysqli_num_rows return an integer for a query with 0 returned rows?

I am having a strange issue with mysqli_num_rows. Searching for this issue, I've only found people having issues where NULL is returned no matter what. I also checked the official documentation for the function, and it says it returns an integer of the number of rows returned by the query. Whenever my query returns 1 row (it never should return more), it behaves as I expect. When the query returns 0 rows, I expect the function to return 0, but it returns NULL. Why doesn't it return 0?
I know that my database connection is good and my query works correctly, because when I look for a record that's in the database, I get an integer back. I just can't figure out why this is returning NULL rather than 0.
function getArtistID($name) {
global $conn;
$query = "SELECT artist_id FROM artist WHERE artist_name LIKE '${name}'";
$result = mysqli_query($conn, $query);
if ($result->num_rows) {
$row = mysqli_fetch_assoc($result);
return $row['artist_id'];
} else {
return 0;
}
}
Here's some code that I used to reproduce a case where num_rows seems to be NULL:
<?php
error_reporting(E_ALL);
$conn = new mysqli('127.0.0.1', 'root', null, 'test');
$sql = "SELECT * FROM dual";
$result = $conn->query($sql);
if ($result === false) {
print "Error: {$conn->error}\n";
}
$n = $result->num_rows;
echo "Dump the num_rows property: ";
var_dump($n);
Output:
Error: No tables used
Notice: Trying to get property of non-object in /Users/bkarwin/Documents/SO/my.php on line 14
Dump the num_rows property: NULL
The notice is because it's invalid to access an object-oriented property of a variable that is not an object. This is a frequent source of confusion for PHP developers, and it's a byproduct of the fact that PHP is a loosely typed language, and functions like query() can return either a result object, or a boolean scalar.
The query() function actually returned a false as $result because of some error. In my code, I checked for this error, and you didn't.
When you run mysqli::query() or mysqli::prepare() or mysqli_stmt::execute(), you must check for error conditions every time.
Something about your query caused an error. It's up to you to check for the error and report it.
Update: I edited some text above to make the explanation better, but it might make some comments below seem out of place.
I just can't figure out why this is returning NULL rather than 0.
We can only guess without seeing the log output; but, it is likely the return value is null because it raised an error instead.
You need to ensure that errors are handled when calling a function, before attempting to use the return value.

php sql search issues

ok here is my code maybe someone out there can explain what I am doing wrong here as I just don't get it. My understanding of this is that IF the stmt finds a result it will then run the code in the {} and hence return a result. And IF there is no result then it would return nothing, as the IF statement is false. But I am getting a return in postman even though the ID that I am searching is false. It does not exist on the table. Why do I get a return?
public function getDoc($ID){
if( $xromstmt = $this->con->prepare("SELECT adegree, bdegree, cset, dset FROM xromdb WHERE ID = ?")) {
$xromstmt->bind_param("s", $ID);
$xromstmt->execute();
$xromstmt->bind_result($adegree, $bdegree, $cset, $dset);
$xromstmt->fetch();
$evalxrom = array();
$edocxrom = array();
some other code here dealing with the return etc... } <-- the end bracket
to the if statement. There is nothing past this bracket.
} bracket to getDoc
The if statement that you have is just checking that the prepare was successful. To see if there was any data returned from the query, you need to check the result of the call to fetch. Try something like this:
if ($xromstmt = $this->con->prepare("SELECT adegree, bdegree, cset, dset FROM xromdb WHERE ID = ?")) {
$xromstmt->bind_param("s", $ID);
$xromstmt->execute();
$xromstmt->bind_result($adegree, $bdegree, $cset, $dset);
if ($xromstmt->fetch()) {
$evalxrom = array();
$edocxrom = array();
...
some other code here dealing with the return etc...
}
}
You should probably also check the result of the call to execute.
The $xromstmt->prepare statement does not search the database it sets-up the search; the database is not searched until $xromstmt->execute. The execute and prepare statements will return true or false if the statement was run correctly (i.e. no errors in your code) regardless of whether any results were found.
What you want is to use is the number of rows from the query, 0 if no results found:
$num_rows = mysql_num_rows($xromstmt)
then run if statements of $num_rows
Hope this helps

Dot (Full Stop) in Get Value Breaks the SQL Query (PDO)

I'm fetching results from MySQL database using PDO and I use value from $_GET request method as a condition. Everything works fine but if there is any fullstop (dot) in the $_GET value, MySQL returns 0 rows.
Here is my sample:
<?php
function filter($val) {
$f = htmlentities($val);
$f = filter_input(INPUT_GET, $f);
return strip_tags($f);
}
$dev = filter("dev");
function DevFetch($dev) {
$q = $this->link->prepare("SELECT app FROM table WHERE dev = ?");
$q->bindValue("1", $dev);
$q->execute();
if($q->rowCount() > 0) {
return $q->fetchAll();
} else {
return false;
}
}
?>
Here are some examples.
Case 1:
results.php?developer=Google+Inc // works fine
Case 2:
results.php?developer=Google // works fine
Case 3:
results.php?developer=Google+Inc. // doesn't work with dot at the end
Please help with this. Note that I'm encoding (urlencode()) the $_GET value as well as filtering it using filter_input() function. Without filtering / encoding also doesn't work.
Since you use prepared statements, you don't need that filter function.
Just that simple:
function DevFetch($dev) {
$q = $this->link->prepare("SELECT app FROM table WHERE dev = ?");
$q->bindValue(1, $dev);
$q->execute();
$result = $q->fetchAll();
if(count($result) > 0) {
return $result;
} else {
return false;
}
}
$input = $_GET["dev"];
DevFetch($input);
Taken directly from the docs:
PDOStatement::rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
This means that this statement (being a SELECT):
$this->link->prepare("SELECT app FROM table WHERE dev = ?");
does not affect the return value of rowCount. To get the row count, you'll have to resort to mysqli or write:
$rows = $stmt->fetchAll();
$rowCount = count($rows);
If what you say is indeed true, and only the value with a dot on the end doesn't return a value for rowCount, then here's a couple of things you really ought to check:
PDO dsn string: specify the charset (add ;charset=utf8 to the end of the DSN string. details here
Set the error mode to have PDO throw exceptions on failure: PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
Check your DB for rows with the value that has the dot on the end, if it isn't there, than your code works as expected, simply because there are no results to work with

mysql_affected_rows to figure out the type of query

I have a utility class in my php code which provides wrapper for some mysql functions. One of the functions named query() accepts the query string as an argument and then performs that query.
In this query function I want to find out if the given query is data state changing query (UPDATE/INSERT/DELETE etc.) or a simple data extraction query (SHOW/SELECT).
I was planning to use mysql_affected_rows function for this as the php manual says this function "Gets the number of affected rows by the last INSERT, UPDATE, REPLACE or DELETE query".
I was assuming I would get a 0 or null for SELECT query. I know even those UPDATE/DELETE queries which do not make any modifications will return 0 but it's ok from my code perspective because I only want to identify those queries which actually did some data modification.
But when I actually executed the code, mysql_affected_rows returns me the number of selected rows for SELECT queries.
Is it the expected behavior? I looked up php manuals but they do not elaborate on what would be the behavior of mysql_affected_rows in case of SELECT queries.
I looked up MySql documentation and it says MySql mysql_affected_rows function is expected to work like mysql_num_rows (which is consistent with the behavior I am seeing).
So is there any other php function which can help me identify the query type without actually parsing the query?
Maybe you trying too complicated, string parsing isn't the worst idea here.
Or do you know any query not beginning with what it's doing?
Multiqueries are not available in mysql_query anyways.
public function query($query) {
$state = null;
if (stripos(trim($query), 'INSERT') === 0) {
$state = 'insert';
}
elseif (stripos(trim($query), 'REPLACE') === 0) {
}
elseif (stripos(trim($query), 'UPDATE') === 0) {
}
elseif (stripos(trim($query), 'SELECT') === 0) {
$state = 'select';
}
elseif (stripos(trim($query), 'SET') === 0) {
$state = 'option';
}
else {
$state = '?';
}
/* ... */
}
Why don't you extract the first word of the sql (string) that the function query receives and perform a comparison condition to the operations
$sql = 'select * from tableName';
$action = explode(' ',trim($sql))[0];
$action = strtoupper($action);
if($action=='UPDATE' || $action == 'INSERT' || $action=='DELETE'){
//do your stuff here
}else{
//it's a show/select query.
}
ps: this is not a working/tested code. just an example to better explain what i'm talking about.

PHP/PDO : No result if a column = 0?

I have a very simple function to check in the DB if we know an Artist (based on a unique ID) and if it's the case, I want to collect his infos :
function isArtistKnown($id_artist){
global $pdo;
$isKnownQuery = $pdo->query("SELECT * FROM artistes WHERE IDArtiste = '$id_artist'");
if($isKnownQuery->rowCount() > 0){
$KnownArtiste = $isKnownQuery->fetch(PDO::FETCH_OBJ);
return $KnownArtiste;
}else{
return $isKnownQuery->errorInfo();
}
}
The problem is following :
If the IDArtiste is known and another colmun called "last_tweet' (INT50) equals 0 then the PDO finds 1 result and $KnownArtiste is filled.
Now, If the IDArtiste is known but the colum "last_tweet" != 0 then the PDO doens't find any result (and errorInfo() equals 0000, which means : no error).
Do you have an idea where the problem comes from ?
The documentation states :
PDO::query() executes an SQL statement in a single function call,
returning the result set (if any) returned by the statement as a
PDOStatement object.
Which means, if there's no match, it returns no rows!
Quoting directly from the PHP PDOStatement::rowCount page:
PDOStatement::rowCount() returns the number of rows affected by the
last DELETE, INSERT, or UPDATE statement executed by the corresponding
PDOStatement object.
If the last SQL statement executed by the associated PDOStatement was
a SELECT statement, some databases may return the number of rows
returned by that statement. However, this behaviour is not guaranteed
for all databases and should not be relied on for portable
applications.
You can't use rowCount with SELECTs. Use this instead:
function isArtistKnown($id_artist){
global $pdo;
//If you don't use prepared statements, a kitten and a puppy die somewhere
$isKnownQuery = $pdo->prepare("SELECT * FROM artistes WHERE IDArtiste = :ida");
$isKnownQuery->bindValue(':ida', $id_artist);
$isKnownQuery->execute();
$KnownArtiste = $isKnownQuery->fetch(PDO::FETCH_OBJ);
if(isset($KnownArtiste->IDArtiste)){
return $KnownArtiste;
}else{
//Actually, in this case there's no error, just no artist
//so i'd use
return null;
//instead of
//return $isKnownQuery->errorInfo();
}
}
If you're going to return errorInfo() it'll always contain data whether there is an error or not. You should be returning a friendly user message to state that there are no rows found (the artist is not known to you)
function isArtistKnown($id_artist){
global $pdo;
$isKnownQuery = $pdo->query("SELECT * FROM artistes WHERE IDArtiste = '$id_artist'");
if ($isKnownQuery->rowCount() === 0){
return false;
}
$KnownArtiste = $isKnownQuery->fetch(PDO::FETCH_OBJ);
return $KnownArtiste
}
and validate:
$Validate = isArtistKnown(0);
if ($Validate === false){
echo "Artist is Not Known";
}else{
//Work with your data
}

Categories