never ending loop : fatal error - php

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.

Related

Join multiple strings from php & sql foreach loop and return as 1 string

I'm trying to build a permission/action control system for my users.
There are 3 tables:
appName_actions:
appName_roles:
appName_roles_members:
There are 2 functions that will obtain the relevant data:
$memRoleIDs = AccessControl::get_memberRoleIDs($appName);
$memActionIDs = AccessControl::get_memberActionIDs($appName, $memRoleIDs);
get_memberRoleIDs works fine, it targets member 327 and returns the desired '2,4'
That is then passed to get_memberActionIDs as '2,4'
It's at this point I'm having trouble working out how to return all the actionIDs in one variable/string.
get_memberActionIDs:
public static function get_memberActionIDs($appName = NULL, $memRoleIDs = NULL)
{
if($appName !== NULL && $memRoleIDs !== NULL)
{
$tbl = 'app_'.$appName.'_roles';
$memRoleID = explode(',',$memRoleIDs);
foreach($memRoleID as $value)
{
$db = openDB();
$sql = $db->prepare("SELECT actionIDs FROM $tbl WHERE roleID = '$value'");
if(!$sql->execute())
{
logThis('ERROR_crit' , 'Database Query Failed !!!' , 1 , __FILE__ , __LINE__);
die('<h2>There was a critical error and data has not been loaded correctly. Developers have been notified.</h2><h3>Please try reloading the page</h3>');
}
else
{
// sql executed ok - bind fetch results
$sql->bind_result($actionID);
$sql->fetch();
print $actionID.'<br>';
}
}// return all the actionIDs as 1 variable here
}
}// end func
Now with this, there is success up-to-a-point. It prints out the correct info:
1,2,3,4
5
And this is where I cannot go any further :(
I've looked into GROUP_CONCAT and CONCAT in the SELECT statement and .= in the PHP loop, but I just cannot figure this out.
I'd like to return this as '1,2,3,4,5' all in 1 string.
If you could point me in the right direction I would be very grateful :)
Instead of printing out separate results, create a single string and print after the loop exits. You say you've tried this but you didn't include the relevant code to check if the implementation is correct. Is this what you did?
public static function get_memberActionIDs($appName = NULL, $memRoleIDs = NULL)
{
if($appName !== NULL && $memRoleIDs !== NULL)
{
$tbl = 'app_'.$appName.'_roles';
$memRoleID = explode(',',$memRoleIDs);
$result = "";
foreach($memRoleID as $value)
{
$db = openDB();
$sql = $db->prepare("SELECT actionIDs FROM $tbl WHERE roleID = '$value'");
if(!$sql->execute())
{
logThis('ERROR_crit' , 'Database Query Failed !!!' , 1 , __FILE__ , __LINE__);
die('<h2>There was a critical error and data has not been loaded correctly. Developers have been notified.</h2><h3>Please try reloading the page</h3>');
}
else
{
// sql executed ok - bind fetch results
$sql->bind_result($actionID);
$sql->fetch();
$result .= $actionID;
}
}// return all the actionIDs as 1 variable here
print $result.'<br>';
}
}// end func

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;
}
?>

Loop to check dupilicate random strings

I have this function which creates random string:
function genID($length) {
$chars = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM#!";
//only allowed chars in the blowfish salt.
$size = strlen($chars); $str = "";
for ($i = 0; $i < $length; $i++)
$str .= $chars[rand(0, $size - 1)]; // strings can be used as char arrays
// Yes, I am aware this salt isn't generated using the OS source.
// use mycrypt_create_iv or /dev/urandom/
return $str;
}
This output something like:
#iBUQvldLq
Now I have users list with something like that:
userid | username | usermail ...
--------------------------------------
#iBUQvldLq test test#gmaik.com ....
Now when some one register I create new string and insert the new string to userid row in database, after that I create a new string, then I check if the new string created doesn't exist, something like this:
function newID()
{
$newid = genID(10);
$query = "SELECT * FROM users WHERE userid = '".$newid."'";
$result1 = mysql_query($query);
$num = mysql_num_rows($result1);
if($num == 1)
{
$newid = genID(10);
return $newid;
}
else
{
return $newid;
}
}
Any one have any idea how to loop on the check function?
I mean the generate function create new random string, then the function check if it already exist, then create new one, if not return the one created.
So now if he create new one, and the new one also match the same other userid, so how I loop until the new string won't match never to other userid string?
Something like loop:
create new string
verify if exist
if exist create new one
if the new one also exist create new one and so on
Till its never match other userid, make a loop, any idea ?
EDITED :
The new function for loop if any need:
function newID(){
$continue = true;
while ($continue) {
$newid = genID(10);
$query = mysql_query("SELECT * FROM users WHERE userid='".$newid."' LIMIT 1");
if (mysql_num_rows($query) != 1)
$continue = false;
return $newid;
}
}
$newid = newID();
It looks like your wanting code like this..
function uHash(){
$continue = true;
while ($continue) {
$hash = substr(MD5(microtime()), 0, 7);
$query = mysql_query("SELECT `Link` FROM Table WHERE `value`='$hash' LIMIT 1");
if (mysql_num_rows($query) != 1)
$continue = false;
return $hash;
}
}
The script will loop until it finds a unique value.
Setting your user_id column as an auto_increment field would solve this issue. [Best Approach]
If you really want to do with PHP, couple uniqid() with rand() to generate a unique seed that doesn't collide.
Something like this
<?php
echo $id = uniqid(rand(), true);
?>
Just you can use for unique id
<?php
function genID() {
return uniqid();
}
echo genID();
?>

unique random id

I am generating unique id for my small application but I am facing some variable scope problem. my code-
function create_id()
{
global $myusername;
$part1 = substr($myusername, 0, -4);
$part2 = rand (99,99999);
$part3 = date("s");
return $part1.$part2.$part3;
}
$id;
$count=0;
while($count == 1)
{
$id;
$id=create_id();
$sqlcheck = "Select * FROM ruser WHERE userId='$id';";
$count =mysql_query($sqlcheck,$link)or die(mysql_error());
}
echo $id;
I dont know which variable I have to declare as global
That doesn't look like a variable scope problem, it looks like a simple variable assign problem:
$count=0;
while($count == 1)
{
This block will clearly never execute.
Further, please use a boolean with a good name when doing boolean checks. It reads so much cleaner. i.e.:
function isUniqueUserID($userIDToCheck)
{
$sqlcheck = "Select * FROM user 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 );
}
Note that mysql_query will use the last used connection if you don't specify a link:
http://us2.php.net/mysql_query
No need to make it global.
in adition to Zak's answer i'd pass the username into the function instead of using globals
function create_id($username)
{
$part1 = substr($username, 0, -4);
$part2 = rand (99,99999);
$part3 = date("s");
return $part1.$part2.$part3;
}
also
//$id; no need for this
$count=1; // this bit
while($count == 1) // not sure what's going on
{
//$id; again same thing no need for this
$id=create_id($myusername);
edit: now that i think of it: how do you expect to find "Select * FROM ruser WHERE userId='$id';"? A Select query is used to find something specific, your username is so random, i think the likely hood of actually successfully getting a record is 1 in a bajillion.
edit2 whoops, i see the whole point is to get a unique username... O_O
In addition to the others:
$count =mysql_query($sqlcheck,$link)or die(mysql_error());
mysql_query doesn't return a record count but, rather, a resource.
mysql_query

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