PHP if random code exists in database regenerate random code - php

I'm attempting to create a PHP script that will create a random code and check it against a database to see if it exists. I'd like it to check that if it exists then generate another createRandomCode() and check it.
Unsure how to proceed with looping until the number of rows are 0.
function createRandomCode($length='6'){
$chars = "abcdefghijkmnopqrstuvwxyz023456789";
srand((double)microtime()*1000000);
$i = 0;
$code= '';
while ($i++ < $length){
$code = $code. substr($chars, rand() % 33, 1);
}
return $code;
}
$shorturl = createRandomCode();
$q = $db - > query("SELECT * FROM maps WHERE url='".$shorturl.
"'");
if (mysqli_num_rows($q) > 0) {
$arr = json_encode($arr);
echo $arr;
}

Sounds like a good candidate for a do...while loop:
do {
$shorturl = createRandomCode();
$q = $db->query("SELECT * FROM maps WHERE url='".$shorturl."'");
} while(mysqli_num_rows($q) > 0);

function regenerateCode(){
global $connection;
do{
$serial2 = rand(0,7);
$check_code = "SELECT * FROM `voters` WHERE `serial` = '$serial2'";
$run_check_code = mysqli_query($connection,$check_code);
$count = mysqli_num_rows($run_check_code);
} while( $count > 0 );
return $serial2;
}

Related

Mysqli Result Fetch_Row Memory Leak

I use mysqli API to query a large table, every 1000 rows, but the memory of my server grows up very fast. The memory is 0, even the swap. I don't know how to fix it.
The table has 4 million rows so I query the table each time by 1000.
Here is my code:
<?php
ini_set('memory_limit','32M');
$config = require_once('config.php');
$attachmentRoot = $config['attachment_root'];
$mysqli = new mysqli($config['DB_HOST'],$config['DB_USER'],$config['DB_PASSWORD'],$config['DB_NAME']);
$mysqli->set_charset('gbk');
if(!$mysqli)
throw new Exception('DB connnect faild:'.mysqli_connect_errno().mysqli_connect_error());
echo "\nRename The Dup Files With Suffix: .es201704111728es \n";
$startTime = microtime(true);
/**
*
* Move dup file to $name + .es201704111728es
*/
$suffix = ".es201704111728es";
$fileLinesLimit = 100000;
$listSuffix = 0;
$lines = 0;
/**
* Create File List.
*/
$fileList = '/tmp/Dupfilelist.txt';
$baseListName = $fileList.$listSuffix;
//$fs = fopen($baseListName,'w');
$totalSize = 0;
$start = 0;
$step = 10000;
$sql = "SELECT id,filepath,ids,duplicatefile,filesize FROM duplicate_attachment WHERE id> $start AND duplicatefile IS NOT NULL LIMIT $step";
$result = $mysqli->query($sql);
while($result->num_rows > 0)
{
while($result->fetch_row())
{
/*$fiepath = $row[1];
$uniqueIdsArray = array_unique(explode(',',$row[2]));if(empty($row[3]))throw new \Exception("\n".'ERROR:'.$row[0]."\n".var_export($row[3],true)."\n");
$uniqueFilesArray = array_unique(explode(',',$row[3]));
$hasFile = array_search($fiepath,$uniqueFilesArray);
if($hasFile !== false)
unset($uniqueFilesArray[$hasFile]);
$num = count($uniqueIdsArray);
$fileNum = count($uniqueFilesArray);
$ids = implode(',',$uniqueIdsArray);
if($num>1 && $fileNum>0){
//echo "\nID: $row[0] . File Need To Rename:".var_export($uniqueFilesArray,true)."\n";
$size = intval($row[4]);
if($lines >= $fileLinesLimit){
$lines = 0;
$listSuffix++;
//$fileList .= $listSuffix;
}
array_map(function($file) use ($attachmentRoot,$suffix,$fiepath,$totalSize,$size,$fileLinesLimit,&$listSuffix,&$lines,$fileList){
//$fs = fopen($fileList.$listSuffix,'a');
if($file === $fiepath)
return -1;
$source = $file;
$target = $source.$suffix;
//rename($source,$target);
//fwrite($fs,$source.','.$target."\n");
//file_put_contents($fileList.$listSuffix, $source.','.$target."\n",FILE_APPEND);
//$totalSize += intval($size);
$lines ++;
//echo memory_get_usage()."\n";
//fclose($fs);
//unset($fs);
//try to write file without amount memory cost
//$ts = fopen('/tmp/tempfile-0412','w');
},$uniqueFilesArray);
//echo "Test Just One Attachment Record.\n";
//echo "Ids:$ids\n";
//exit();
}*/
}
echo memory_get_peak_usage(true)."\n";
if(!$mysqli->ping())
{
echo "Mysql Conncect Failed.Reconnecting.\n";
$mysqli = new mysqli($config['DB_HOST'],$config['DB_USER'],$config['DB_PASSWORD'],$config['DB_NAME']);
$mysqli->set_charset('gbk');
if(!$mysqli)
throw new Exception('DB connnect faild:'.mysqli_connect_errno().mysqli_connect_error());
}
//mysqli_free_result($result);
$result->close();
unset($result);
$start += $step;
$sql = "SELECT id,filepath,ids,duplicatefile,filesize FROM duplicate_attachment WHERE id> $start AND duplicatefile IS NOT NULL LIMIT $step";
$result = $mysqli->query($sql);
}
echo "Dup File Total Size: $totalSize\n";
echo "Script cost time :".(microtime(true)-$startTime)." ms\n";sleep(1000*10);
mysqli_close($mysqli);
exit();
I enable the XDEBUG extension.Sorry for that.
I disable this extension and everything goes well.
I ran into this issue with PHP Version 7.3.26 on Centos 7. I worked around it by using unbuffered query (instead of buffered). In the above example, replace
$result = $mysqli->query($sql)
with
$result = $mysqli->query($sql, MYSQLI_USE_RESULT)

Pagination for foreach loop

I currently have a method inside my "car class" that display the car:
static function getCars(){
$autos = DB::query("SELECT * FROM automoviles");
$retorno = array();
foreach($autos as $a){
$automovil = automovil::fromDB($a->marca, $a->modelo, $a->version, $a->year, $a->usuario_id, $a->kilometraje, $a->info,
$a->hits, $a->cilindrada, $a->estado, $a->color, $a->categoria, $a->precio, $a->idAutomovil);
array_push($retorno, $automovil);
}
return $retorno;
}
In my index.php I call that function
foreach(car::getCars() as $a){
That allows me to display the info this way ( of course inside the foreach I have a huge code with the details I'll display.
Is there a way to implement a pagination to that thing so I can handle 8 cars per page, instead of showing all of them at the same page?
You can add a $limit and $page parameter on your function so that it will only return a maximum of $limit number of items starting from $limit * $page(or will call it the $offset). You also need to add a function to get the total number of rows you have for automoviles table.
static function getCars($page = 0, $limit = 8){
$offset = $limit * max(0, $page - 1);
//replace this with prepared statement
$autos = DB::query("SELECT * FROM automoviles LIMIT $offset, $limit");
$retorno = array();
foreach($autos as $a){
$automovil = automovil::fromDB($a->marca, $a->modelo, $a->version, $a->year, $a->usuario_id, $a->kilometraje, $a->info,
$a->hits, $a->cilindrada, $a->estado, $a->color, $a->categoria, $a->precio, $a->idAutomovil);
array_push($retorno, $automovil);
}
return $retorno;
}
static function getTotal()
{
//query to get total number of rows in automoviles table
}
In your index.php do this:
foreach(car::getCars((isset($_GET['page']) ? $_GET['page'] : 1)) as $a){
...
}
and add the pagination links.
$total = car::getTotal();
if($total > 8) {
for($i = 1; $i <= intval(ceil(1.0 * $total / $limit)); $i++) {
echo '' . $i . ';
}
}

Unexpected variable scope in PHP

I would like to show 3 random images from database in my website. Below is its code:
$query = mysql_query ("SELECT id,url FROM tbl_gallery2");
if (mysql_num_rows($query) >= 3) {
$my_array = array();
$last_array = array();
while ($r = mysql_fetch_row($query)) {
$my_array[] = $r[1];
}
function makernd () {
$number = array_rand($my_array,1);
if (in_array($number,$last_array)) {
makernd();
} else {
$last_array[] = $number;
return $number;
}
}
for($i = 1 ; $i < 3 ; $i++) {
$item = makernd();
echo '<img src="./images/slider/'.$item.'.jpg" alt="" class="slider" />';
}
}
But whenever I run this code, I get the error below:
Undefined variable: my_array in line ... // The first line of makernd() function.
But I expected $my_array to be an accessible array for this function.
What's the problem?
To simply fix your problem, you should pass $my_array to makernd() as a parameter:
$query = mysql_query ("SELECT id,url FROM tbl_gallery2");
if (mysql_num_rows($query) >= 3) {
$my_array = array();
$last_array = array();
while ($r = mysql_fetch_row($query)) {
$my_array[] = $r[1];
}
function makernd ($my_array) {
$number = array_rand($my_array,1);
if (in_array($number,$last_array)) {
makernd($my_array);
} else {
$last_array[] = $number;
return $number;
}
}
for($i = 1 ; $i < 3 ; $i++) {
$item = makernd($my_array);
echo '<img src="./images/slider/'.$item.'.jpg" alt="" class="slider" />';
}
}
HOWEVER, I strongly suggest putting the randomization in MySQL, to
Simplify your code
Significantly improve the performance, and
Eliminate excessive loops & recursion in PHP
Example:
$sql = "SELECT id,url
FROM tbl_gallery2
ORDER BY RAND()
LIMIT 3";
$query = mysql_query ($sql);
if (mysql_num_rows($query) >= 3) {
while ($r = mysql_fetch_row($query)) {
echo '<img src="./images/slider/' . $r[1] . '.jpg" alt="" class="slider" />';
}
}
PS - I also suggest you update your code to use mysqli, as mysql is deprecated
PPS - I also suggest you look into mysqli_fetch_assoc so you can reference query results by name instead of index (e.g. $r['url'] instead of $r[1] - as if you ever change the order of your query, you will break references by index.

Split total into 5 different numbers

Ok what i'm wanting to do is split a number ($row['count']) into 5, this is easy enough if you want equal numbers:
$sum = ($row['count'] / 5);
$fsum = floor($sum);
but I want each number to be different and still add up to total ie $row['count'] how can this be achieved?
Update:
If this helps its to be used to update 5 rows in a database:
$query = "SELECT * FROM foo";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
$sum = ($row['count'] / 5);
$fsum = floor($sum);
$id = $row['id'];
$update = "UPDATE foo SET foo1='$fsum', foo2='$fsum', foo3='$fsum', foo4='$fsum', foo5='$fsum' WHERE id='$id'";
mysql_query($update);
}// while
so ideally the $update query would be something like:
$update = "UPDATE foo SET foo1='$fsum1', foo2='$fsum2', foo3='$fsum3', foo4='$fsum4', foo5='$fsum5' WHERE id='$id'";
This is my take:
function randomize($sum, $parts) {
$part_no = count($parts);
$continnue_counter = 0;
while (count(array_unique($parts)) != $part_no) {
$changing = array_rand($parts, 2);
if (($parts[$changing[0]] - 1) == 0 || ($parts[$changing[1]] - 1) == 0) { // don't let them go under 1
++$continnue_counter;
// sometime one element get everything and others even out on 1
// just throw away everything you got so far and start over
if ($continnue_counter > 10) {
$parts = setup($sum, $part_no);
$continnue_counter = 0;
}
continue;
}
$continnue_counter = 0;
$signum = mt_rand(0, 100) % 2 ? 1 : -1;
$delta = $signum * mt_rand(1, min($parts[$changing[0]] - 1, $parts[$changing[1]] - 1)); // -1 to make sure they don't go under 0
$parts[$changing[0]] += $delta;
$parts[$changing[1]] -= $delta;
}
return $parts;
}
function setup($sum, $part_no) {
$parts = array_fill(0, $part_no, (int)($sum / $part_no));
// acount for the reminder of (int) cast
$reminder = $sum - array_sum($parts);
while ($reminder) {
$parts[array_rand($parts)] += 1;
--$reminder;
}
return $parts;
}
$part_no = 5;
$sum = 42;
$parts = randomize($sum, setup($sum, $part_no));
var_export($parts);
print array_sum($parts)
Update:
I've added a version that introduces a little more entropy.
Update2:
The more random one had a tendency to decrement everything to 1 except one part, added an explicit detection to deal with this. Still the algorithm behind it has unknown termination time.

Select lowest price from database row and ignore null or 0

I have a database called prices and there are 12 columns lets say.
comp1, comp2, comp3, comp4, comp5, comp6 and so on.
I then want to run a query to find the lowest price stored in that row that matches an id, however I think it is treating null as lowest value as I am not getting the correct answer.
Anyway around this? or am i doing this wrong?
$query = "SELECT * FROM Prices WHERE id =$id" or die(mysql_error());
$result = mysql_query($query) or die(mysql_error());
while ($row = mysql_fetch_array($result)) {
$comp1= $row['comp1'];
$comp2= $row['comp2'];
$comp3= $row['comp3'];
$comp4= $row['comp4'];
$comp5= $row['comp5'];
$comp6= $row['comp6'];
$comp7= $row['comp7'];
$comp8= $row['comp8'];
$comp9= $row['comp9'];
$comp10= $row['comp10'];
$comp11= $row['comp11'];
$comp12= $row['comp12'];
$min = array( $comp1, $comp2, $comp3, $comp4, $comp5, $comp6, $comp7, $comp8, $comp8, $comp10, $comp11, $comp12);
echo min($min);
}
If you call array_filter() on the array before calling min(), you will purge anything that evaluates to false, including null and 0.
For example: $min = min(array_filter($min));
Try:
$min = array( $comp1, $comp2, $comp3, $comp4, $comp5, $comp6, $comp7, $comp8, $comp8, $comp10, $comp11, $comp12);
$min = array_filter($min);
echo min($min);
From a comment in http://php.net/manual/en/function.min.php:
I've modified the bugfree min-version to ignore NULL values (else it returns 0).
<?php
function min_mod () {
$args = func_get_args();
if (!count($args[0])) return false;
else {
$min = false;
foreach ($args[0] AS $value) {
if (is_numeric($value)) {
$curval = floatval($value);
if ($curval < $min || $min === false) $min = $curval;
}
}
}
return $min;
}
?>
Try this:
$query = "SELECT * FROM Prices WHERE id =$id" or die(mysql_error());
$result = mysql_query($query) or die(mysql_error());
while ($row = mysql_fetch_array($result)) {
$i= 0;
foreach ($row as $val) {
if ($i == 0) {
$tmpMin = $val;
} else {
if ($tmpMin < $val) {
$val = $tmpMin;
}
}
}
unset($tmpMin);
echo $tmpMin;
}

Categories