PHP's return syntax and semantics - php

What's the difference between two function A,F? sorry for using mysql instead of mysqli or PDO
function A ($B){
if($result = mysql_query("SELECT C FROM D WHERE E"))
{
if ($row = mysql_fetch_array($result))
{
return $text = $row['C'];
}
return 0;
}
return 0;
}
and this one:
function F ($G){
if($result = mysql_query("SELECT C FROM D WHERE E"))
{
if ($row = mysql_fetch_array($result))
{
return $row['C'];
}
}
return 0;
}

The end result in both cases is the same (as they are now), since both functions will return the value of column C if queries are successful and return a result.
On the first example A will also return 0 if the query is successful but no results are returned hence if you modify it as:
function A ($B){
if($result = mysql_query("SELECT C FROM D WHERE E"))
{
if ($row = mysql_fetch_array($result))
{
return $text = $row['C'];
}
return 0;
}
return 1;
}
if the returned value is 0 you'll know the query was successfull but if the return value was 1 it will mean the query execution failed. That is if C does not contain the values 0 or 1 where in that case you wouldn't really be sure on whether the returned 0 or 1 is the return value of column C or the function's actual return statement
UPDATE
To distinguish between the two you could return false if something has failed:
return false;
and then check if the return value of the function is really false:
if(A() === false)
{
// something went wrong, do something else
}
Note: See the ===, it makes sure that the equality check only checks for boolean value false and that string "false" or values 0 or '0' are not classified as false

Related

pg_fetch_assoc returns boolean

I'm making a script to insert/update data from a mysql database to a postgres database.
if ($result->num_rows > 0)
{
while($row = $result->fetch_assoc())
{
$postgres = "SELECT * FROM res_partner";
echo $postgres . "\n";
$pgresult = pg_query($db,$postgres);
$a = 0;
if(pg_num_rows($pgresult) > 0)
{
while($pgrow = pg_fetch_assoc($pgresult))
{
if($pgrow["id"] == $row["customer_id"])
{
$a + 1;
}
else
{
$a + 0;
}
}
var_dump($pgrow);
exit();
I want to check if the id in mysql database is also in the postgres database.
But the $pgrow returns "bool(false)" with my var_dump.
I have no idea why.
Because the var_dump() is outside the while loop.
The loop will continue to call pg_fetch_assoc until it returns false
Place the call inside the loop to see the contents of the current row:
while($pgrow = pg_fetch_assoc($pgresult))
{
if($pgrow["id"] == $row["customer_id"])
{
$a + 1;
}
else
{
$a + 0;
}
var_dump($pgrow);
}
Or use a proper debugger like XDebug to avoid having to write code like this
Can't you just do something like SELECT true FROM res_partner WHERE id = $customer_id so as not to do the while loop?
Then you would get either one row with a single value true if it exists, or false because no rows were returned.

Converting mysql_* to mysqli_* issue with mysql_result [duplicate]

I'm porting some old PHP code from mysql to MySQLi, and I've ran into a minor snag.
Is there no equivalent to the old mysql_result() function?
I know mysql_result() is slower than the other functions when you're working with more than 1 row, but a lot of the time I have only 1 result and 1 field. Using it lets me condense 4 lines into 1.
Old code:
if ($r && mysql_num_rows($r))
$blarg = mysql_result($r, 0, 'blah');
Desired code:
if ($r && $r->num_rows)
$blarg = $r->result(0, 'blah');
But there is no such thing. :(
Is there something I'm missing? Or am I going to have to suck it up and make everything:
if ($r && $r->num_rows)
{
$row = $r->fetch_assoc();
$blarg = $row['blah'];
}
The following function fully replicates the mysql_result() function, and returns false when you are out-of-bounds on your request (empty result, no row of that number, no column of that number). It does have the added benefit that, if you don't specify the row, it assumes 0,0 (one less value to be passed). The function allows for the numerical offset of the field or the field name.
function mysqli_result($res,$row=0,$col=0){
$numrows = mysqli_num_rows($res);
if ($numrows && $row <= ($numrows-1) && $row >=0){
mysqli_data_seek($res,$row);
$resrow = (is_numeric($col)) ? mysqli_fetch_row($res) : mysqli_fetch_assoc($res);
if (isset($resrow[$col])){
return $resrow[$col];
}
}
return false;
}
PHP 5.4 now supports function array dereferencing and 7.0 supports a null coalescing operator, which means you can simply do this:
$value = $r->fetch_assoc()['blah'] ?? false;
or even more generic variant where you don't need to supply the column name,
$value = $r->fetch_row()[0] ?? false;
note that you don't even need the if ($r && $r->num_rows) condition.
You can do this by fetching an object instead of an array.
$mysqli->query("SELECT email FROM users WHERE userid = 'foo'")->fetch_object()->email;
function db_result($result,$row,$field) {
if($result->num_rows==0) return 'unknown';
$result->data_seek($row);
$ceva=$result->fetch_assoc();
$rasp=$ceva[$field];
return $rasp;
}
Well, you can always shorten it to something like this:
if ($r && $r->num_rows)
list($blarg) = $r->fetch_row();
But that might be as good as you're going to get.
I suggest you to add this line to Cris' solution in order to be able to get a result by both doing db_result('mytable.myfield) and db_result('myfield') since it is the default behavior of the original mysql_result function.
function db_result($result,$row,$field) {
if($result->num_rows==0) return 'unknown';
$result->data_seek($row);
$ceva=$result->fetch_assoc();
return (isset($ceva[$field])?$ceva[$field]
:(strpos($field,'.')?$ceva[substr($field,strrpos($field,'.')+1)]:''));
}
I use the following function to replace mysql_result()
function mysqli_result($result, $iRow, $field = 0)
{
if(!mysqli_data_seek($result, $iRow))
return false;
if(!($row = mysqli_fetch_array($result)))
return false;
if(!array_key_exists($field, $row))
return false;
return $row[$field];
}
I ended up using a custom function using procedural style:
function mysqli_result($res, $row, $field=0) {
mysqli_data_seek($res, $row);
return mysqli_fetch_array($res)[$field];
}
Reference: https://www.sitepoint.com/community/t/change-mysql-result-to-mysqli/190972/6
You don't need mysql_result() or any similar function.
If you would like to access any column from any row in the result set, the best way is to fetch all into an array using mysqli_fetch_all().
$data = $result->fetch_all(MYSQLI_BOTH);
$var1 = $data[0]['column']; // column from the first row
$var2 = $data[1][2]; // third column from the second row
To prevent access to non-existent values, you can use the null-coalesce operator and provide default value. e.g. $data[1][2] ?? null;.
As of PHP 8.1, mysqli also offers method called fetch_column(). You can use it if you only want to fetch a single value from the result.
$value = $mysqli->query("SELECT email FROM users WHERE userid = 'foo'")->fetch_column(0);
If you select only ONE field in the query and you only expect a single returned data of a selected field, then this works:
function mysqli_datum($result)
{
if ($result->num_rows == 0)
return;
$result->data_seek(0);
$row=$result->fetch_row();
return $row[0];
}
Here's an adaptation of Mario Lurig's answer using a mysqli_result object instead of the procedural version of mysqli.
/**
* Accepts int column index or column name.
*
* #param mysqli_result $result
* #param int $row
* #param int|string $col
* #return bool
*/
function resultMysqli(mysqli_result $result,$row=0,$col=0) {
//PHP7 $row can use "int" type hint in signature
$row = (int)$row; // PHP5 - cast to int
if(!is_numeric($col) ) { // cast to string or int
$col = (string)$col;
} else {
$col = (int)$col;
}
$numrows = $result->num_rows;
if ($numrows && $row <= ($numrows-1) && $row >=0) {
$result->data_seek($row);
$resrow = (is_numeric($col)) ? $result->fetch_row() : $result->fetch_assoc();
if (isset($resrow[$col])){
return $resrow[$col];
}
}
return false;
}
This is a good answer, from http://php.net/manual/es/class.mysqli-result.php
<?php
function mysqli_result($result,$row,$field=0) {
if ($result===false) return false;
if ($row>=mysqli_num_rows($result)) return false;
if (is_string($field) && !(strpos($field,".")===false)) {
$t_field=explode(".",$field);
$field=-1;
$t_fields=mysqli_fetch_fields($result);
for ($id=0;$id<mysqli_num_fields($result);$id++) {
if ($t_fields[$id]->table==$t_field[0] && $t_fields[$id]->name==$t_field[1]) {
$field=$id;
break;
}
}
if ($field==-1) return false;
}
mysqli_data_seek($result,$row);
$line=mysqli_fetch_array($result);
return isset($line[$field])?$line[$field]:false;
}
?>

cant return 2 variables in php by calling return function?

1st i have to say that i am not php professional and this is my 1st time to use return().
so here is the code.
i need to return false and the number of minutes left from the function.
if(!checkIpn())
$err[]='you need to wait'.$nresting.'minutes before you send another request';
function checkIpn()
{
$useripe = 0;
if ( isset($_SERVER["REMOTE_ADDR"]) ) { $useripe = $_SERVER["REMOTE_ADDR"] ; }
else if ( isset($_SERVER["HTTP_X_FORWARDED_FOR"]) ) { $useripe = $_SERVER["HTTP_X_FORWARDED_FOR"] ; }
else if ( isset($_SERVER["HTTP_CLIENT_IP"]) ) { $useripe = $_SERVER["HTTP_CLIENT_IP"] ; }
$query = "SELECT * FROM table WHERE ip = '$useripe' AND status = 'pending' ORDER BY id ASC";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_num_rows($result);
if ( $num_rows > 0 )
{
$str_today = date("Y-m-d H:i:s");
$i=1;
while($row = mysql_fetch_assoc($result))
{
$str_start = $row['date'];
$str_start = strtotime($str_start);
$str_end = strtotime($str_today);
$nseconds = $str_end - $str_start;
$nminutes = round($nseconds / 60);
if ( $nminutes > 120 )
{ return true; }
else {
$nresting = 120 - $nminutes;
return false; }
$i++;
}
}
else { return true; }
based on Tadeck answer below.i did it like this:
$result = checkIpn();
if($result[0]==false)
$err[]='you need to wait '.$result[1].' minutes before you send another request';
thank you Tadeck.
If you want to return two different variables using single call, you can use something like:
return array(true, 0);
or
return array(true);
in first case (when returning success) and
return array(false, $minutes);
in second case (returning failure).
Then you can check it that way:
$result = checkIpn();
if ($result[0]) {
echo 'Success.';
} else {
echo 'Failure. Minutes to wait: '.$result[1];
}
I hope this helps.
EDIT:
If I understand you correctly, you return true or the number of minutes > 0 (larger than zero). Thus you can use such return in case of success:
return true;
and this in case of failure:
return $minutes;
Then you will be able to use it in the code in the following way:
$result = checkIpn();
if ($result === true) {
echo 'Success';
} else {
echo 'Failure. Minutes to wait: '.$result;
}
And I would like to advise you to properly document such function, so that no one is surprised when it returns integer instead of boolean ;)
You can return an array instead of booleans, which allows you to return more than one value:
return array('success'=>FALSE, 'nminutes'=>$nminutes);
But as an alternative, you can just return NULL if the function is successful and return the number of minutes if not. Then you don't need TRUE/FALSE at all.
if ($nminutes > 120)
{
return NULL;
}
else
{
return $nminutes;
}
Check the success like so:
if (checkIpn() !== NULL) // you have minutes left
else // no minutes left - your TRUE case.
You could return an array containing as many things as you like.
In php you can return an array and use the list() function to unpack the values.
function myfn() {
return array(true, 120);
}
...
list($retval, $minutes) = myfn();
This is generally pretty bad style though and I would recommend finding a way to accomplish what you need with 1 return value.

never ending loop : fatal error

my code-
function create_id()
{
//global $myusername;
$part1 = substr("Piyush", 0, -4);
$part2 = rand (99,99999);
$part3 = date("s");
return $part1.$part2.$part3;
}
echo create_id(); //this is printing fine.
function isUniqueUserID($userIDToCheck)
{
$sqlcheck = "Select * FROM ruser WHERE userId='$userIDToCheck';";
$resource = mysql_query($sqlcheck)or die(mysql_error());
$count = mysql_fetch_assoc($resource);
if( count($count) > 0)
{return false;}
return true;
}
$userIDVerifiedUnique = false;
while(! $userIDVerifiedUnique )
{
$userIDToCheck = create_id();
$userIDVerifiedUnique = isUniqueUserID($userIDToCheck );
}
loop is just going on and on from while loop to function IsUniqueUser() and vice versa.????
If there are no rows returned from the MySQL query (i.e. the $userIDToCheck is not in the table, it is unique) then mysql_fetch_assoc will return FALSE. When that happens, count(FALSE) returns 1 (one)! Since that value is greater than zero the function returns FALSE.
In short, if there is a row returned (the string is not unique) your isUniqueUserID function returns FALSE; if there is no row returned (the string is unique) it still returns FALSE.
A simple, new, function to check on the database table could look something like the following...
function isUniqueUserID($userIDToCheck)
{
$userIDToCheck = mysql_real_escape_string($userIDToCheck); // Assume not already escaped
$sqlcheck = "SELECT 1 FROM ruser WHERE userId='$userIDToCheck' LIMIT 1";
$resource = mysql_query($sqlcheck) or die(mysql_error());
return (bool) mysql_num_rows($resource);
}
First, try changing your isUniqueUserID() function to this
function isUniqueUserID($userIDToCheck)
{
$userIDToCheck = mysql_real_escape_string($userIDToCheck); //prevent SQL injection
$sqlcheck = "Select userId FROM ruser WHERE userId='$userIDToCheck';";
$resource = mysql_query($sqlcheck)or die(mysql_error());
$count = mysql_num_rows($resource);
return ($count > 0) ? false : true;
There's no point in returning an associative array just to count the number of rows in it. And there's no point in doing a SELECT * when counting just do SELECT userId since that's all you're concerned with.
I don't see any other reason that isUniqueUserID() would return false unless your ruser table has every possible ID.

MySQLi equivalent of mysql_result()?

I'm porting some old PHP code from mysql to MySQLi, and I've ran into a minor snag.
Is there no equivalent to the old mysql_result() function?
I know mysql_result() is slower than the other functions when you're working with more than 1 row, but a lot of the time I have only 1 result and 1 field. Using it lets me condense 4 lines into 1.
Old code:
if ($r && mysql_num_rows($r))
$blarg = mysql_result($r, 0, 'blah');
Desired code:
if ($r && $r->num_rows)
$blarg = $r->result(0, 'blah');
But there is no such thing. :(
Is there something I'm missing? Or am I going to have to suck it up and make everything:
if ($r && $r->num_rows)
{
$row = $r->fetch_assoc();
$blarg = $row['blah'];
}
The following function fully replicates the mysql_result() function, and returns false when you are out-of-bounds on your request (empty result, no row of that number, no column of that number). It does have the added benefit that, if you don't specify the row, it assumes 0,0 (one less value to be passed). The function allows for the numerical offset of the field or the field name.
function mysqli_result($res,$row=0,$col=0){
$numrows = mysqli_num_rows($res);
if ($numrows && $row <= ($numrows-1) && $row >=0){
mysqli_data_seek($res,$row);
$resrow = (is_numeric($col)) ? mysqli_fetch_row($res) : mysqli_fetch_assoc($res);
if (isset($resrow[$col])){
return $resrow[$col];
}
}
return false;
}
PHP 5.4 now supports function array dereferencing and 7.0 supports a null coalescing operator, which means you can simply do this:
$value = $r->fetch_assoc()['blah'] ?? false;
or even more generic variant where you don't need to supply the column name,
$value = $r->fetch_row()[0] ?? false;
note that you don't even need the if ($r && $r->num_rows) condition.
You can do this by fetching an object instead of an array.
$mysqli->query("SELECT email FROM users WHERE userid = 'foo'")->fetch_object()->email;
function db_result($result,$row,$field) {
if($result->num_rows==0) return 'unknown';
$result->data_seek($row);
$ceva=$result->fetch_assoc();
$rasp=$ceva[$field];
return $rasp;
}
Well, you can always shorten it to something like this:
if ($r && $r->num_rows)
list($blarg) = $r->fetch_row();
But that might be as good as you're going to get.
I suggest you to add this line to Cris' solution in order to be able to get a result by both doing db_result('mytable.myfield) and db_result('myfield') since it is the default behavior of the original mysql_result function.
function db_result($result,$row,$field) {
if($result->num_rows==0) return 'unknown';
$result->data_seek($row);
$ceva=$result->fetch_assoc();
return (isset($ceva[$field])?$ceva[$field]
:(strpos($field,'.')?$ceva[substr($field,strrpos($field,'.')+1)]:''));
}
I use the following function to replace mysql_result()
function mysqli_result($result, $iRow, $field = 0)
{
if(!mysqli_data_seek($result, $iRow))
return false;
if(!($row = mysqli_fetch_array($result)))
return false;
if(!array_key_exists($field, $row))
return false;
return $row[$field];
}
I ended up using a custom function using procedural style:
function mysqli_result($res, $row, $field=0) {
mysqli_data_seek($res, $row);
return mysqli_fetch_array($res)[$field];
}
Reference: https://www.sitepoint.com/community/t/change-mysql-result-to-mysqli/190972/6
You don't need mysql_result() or any similar function.
If you would like to access any column from any row in the result set, the best way is to fetch all into an array using mysqli_fetch_all().
$data = $result->fetch_all(MYSQLI_BOTH);
$var1 = $data[0]['column']; // column from the first row
$var2 = $data[1][2]; // third column from the second row
To prevent access to non-existent values, you can use the null-coalesce operator and provide default value. e.g. $data[1][2] ?? null;.
As of PHP 8.1, mysqli also offers method called fetch_column(). You can use it if you only want to fetch a single value from the result.
$value = $mysqli->query("SELECT email FROM users WHERE userid = 'foo'")->fetch_column(0);
If you select only ONE field in the query and you only expect a single returned data of a selected field, then this works:
function mysqli_datum($result)
{
if ($result->num_rows == 0)
return;
$result->data_seek(0);
$row=$result->fetch_row();
return $row[0];
}
Here's an adaptation of Mario Lurig's answer using a mysqli_result object instead of the procedural version of mysqli.
/**
* Accepts int column index or column name.
*
* #param mysqli_result $result
* #param int $row
* #param int|string $col
* #return bool
*/
function resultMysqli(mysqli_result $result,$row=0,$col=0) {
//PHP7 $row can use "int" type hint in signature
$row = (int)$row; // PHP5 - cast to int
if(!is_numeric($col) ) { // cast to string or int
$col = (string)$col;
} else {
$col = (int)$col;
}
$numrows = $result->num_rows;
if ($numrows && $row <= ($numrows-1) && $row >=0) {
$result->data_seek($row);
$resrow = (is_numeric($col)) ? $result->fetch_row() : $result->fetch_assoc();
if (isset($resrow[$col])){
return $resrow[$col];
}
}
return false;
}
This is a good answer, from http://php.net/manual/es/class.mysqli-result.php
<?php
function mysqli_result($result,$row,$field=0) {
if ($result===false) return false;
if ($row>=mysqli_num_rows($result)) return false;
if (is_string($field) && !(strpos($field,".")===false)) {
$t_field=explode(".",$field);
$field=-1;
$t_fields=mysqli_fetch_fields($result);
for ($id=0;$id<mysqli_num_fields($result);$id++) {
if ($t_fields[$id]->table==$t_field[0] && $t_fields[$id]->name==$t_field[1]) {
$field=$id;
break;
}
}
if ($field==-1) return false;
}
mysqli_data_seek($result,$row);
$line=mysqli_fetch_array($result);
return isset($line[$field])?$line[$field]:false;
}
?>

Categories