jqGrid integrated toolbar search not working - php
I am trying to get the integrated search toolbars working on my page, however I am not having any luck. The regular search function is working for me, but whenever I type anything into the integrated toolbars, it returns 0 results.
Here is my jquery:
$("#parts_table").jqGrid({
url:'testparts2.php',
datatype: "json",
colNames:['Part ID','Name', 'Description', 'Weight'],
colModel:[
{name:'part_ID',index:'part_ID', search: true, stype:'text', width:55},
{name:'part_name',index:'part_name', width:90},
{name:'part_desc',index:'part_desc', width:100},
{name:'part_weight',index:'part_weight', width:80, align:"right"},
],
rowNum:30,
rowList:[10,20,30],
pager: '#pager2',
sortname: 'part_ID',
viewrecords: true,
sortorder: "asc",
caption:"Parts in Database",
width: '800',
height: '300',
});
$("#parts_table").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false});
$("#parts_table").jqGrid('filterToolbar',{stringResult: false,searchOnEnter : false, defaultSearch: 'cn', ignoreCase: true});
and here is my PHP code:
<?php
include "begin.php";
$page = $_REQUEST['page']; // get the requested page
$limit = $_REQUEST['rows']; // get how many rows we want to have into the grid
$sidx = $_REQUEST['sidx']; // get index row - i.e. user click to sort
$sord = $_REQUEST['sord']; // get the direction
if(!$sidx) $sidx =1;
//array to translate the search type
$ops = array(
'eq'=>'=', //equal
'ne'=>'<>',//not equal
'lt'=>'<', //less than
'le'=>'<=',//less than or equal
'gt'=>'>', //greater than
'ge'=>'>=',//greater than or equal
'bw'=>'LIKE', //begins with
'bn'=>'NOT LIKE', //doesn't begin with
'in'=>'LIKE', //is in
'ni'=>'NOT LIKE', //is not in
'ew'=>'LIKE', //ends with
'en'=>'NOT LIKE', //doesn't end with
'cn'=>'LIKE', // contains
'nc'=>'NOT LIKE' //doesn't contain
);
function getWhereClause($col, $oper, $val){
global $ops;
if($oper == 'bw' || $oper == 'bn') $val .= '%';
if($oper == 'ew' || $oper == 'en' ) $val = '%'.$val;
if($oper == 'cn' || $oper == 'nc' || $oper == 'in' || $oper == 'ni') $val = '%'.$val.'%';
return " WHERE $col {$ops[$oper]} '$val' ";
}
$where = ""; //if there is no search request sent by jqgrid, $where should be empty
$searchField = isset($_GET['searchField']) ? $_GET['searchField'] : false;
$searchOper = isset($_GET['searchOper']) ? $_GET['searchOper']: false;
$searchString = isset($_GET['searchString']) ? $_GET['searchString'] : false;
if ($_GET['_search'] == 'true') {
$where = getWhereClause($searchField,$searchOper,$searchString);
}
$totalrows = isset($_REQUEST['totalrows']) ? $_REQUEST['totalrows']: false;
if($totalrows) {
$limit = $totalrows;
}
$result = mysql_query("SELECT COUNT(*) AS count FROM parts");
$row = mysql_fetch_array($result,MYSQL_ASSOC);
$count = $row['count'];
if( $count >0 ) {
$total_pages = ceil($count/$limit);
} else {
$total_pages = 0;
}
if ($page > $total_pages) $page=$total_pages;
if ($limit<0) $limit = 0;
$start = $limit*$page - $limit; // do not put $limit*($page - 1)
if ($start<0) $start = 0;
$SQL = "SELECT * FROM parts ".$where." ORDER BY $sidx $sord LIMIT $start , $limit";
$result = mysql_query( $SQL ) or die("Couldn't execute query.".mysql_error());
$response->page = $page;
$response->total = $total_pages;
$response->records = $count;
$i=0;
while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
$response->rows[$i]['part_ID']=$row[part_ID];
$response->rows[$i]['cell']=array($row[part_ID],$row[part_name],$row[part_desc],$row[part_weight]);
$i++;
}
echo json_encode($response);
?>
It took me hours of searching to find a PHP example that worked for regular searching (see above), however it doesn't seem to work for the toolbar searching. Can anyone help? Thanks
edit: Here is code from jqGrid's demo folder for using this search, but it appears to be full of errors and I have no idea how to use it for my case. I don't need to specify data type for the searches (they are all varchars, so strings will work fine)..so I think that I can strip out the switch/case part for value conversion. I think I just need to change my original code to use $_REQUEST['filters'] and a foreach loop to build the query, but I'm not that great with PHP so any help is appreciated.
demo code:
$wh = "";
$searchOn = Strip($_REQUEST['_search']);
if($searchOn=='true') {
$searchstr = Strip($_REQUEST['filters']);
$wh= constructWhere($searchstr);
//echo $wh;
}
function constructWhere($s){
$qwery = "";
//['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc']
$qopers = array(
'eq'=>" = ",
'ne'=>" <> ",
'lt'=>" < ",
'le'=>" <= ",
'gt'=>" > ",
'ge'=>" >= ",
'bw'=>" LIKE ",
'bn'=>" NOT LIKE ",
'in'=>" IN ",
'ni'=>" NOT IN ",
'ew'=>" LIKE ",
'en'=>" NOT LIKE ",
'cn'=>" LIKE " ,
'nc'=>" NOT LIKE " );
if ($s) {
$jsona = json_decode($s,true);
if(is_array($jsona)){
$gopr = $jsona['groupOp'];
$rules = $jsona['rules'];
$i =0;
foreach($rules as $key=>$val) {
$field = $val['field'];
$op = $val['op'];
$v = $val['data'];
if($v && $op) {
$i++;
// ToSql in this case is absolutley needed
$v = ToSql($field,$op,$v);
if ($i == 1) $qwery = " AND ";
else $qwery .= " " .$gopr." ";
switch ($op) {
// in need other thing
case 'in' :
case 'ni' :
$qwery .= $field.$qopers[$op]." (".$v.")";
break;
default:
$qwery .= $field.$qopers[$op].$v;
}
}
}
}
}
return $qwery;
}
function ToSql ($field, $oper, $val) {
// we need here more advanced checking using the type of the field - i.e. integer, string, float
switch ($field) {
case 'id':
return intval($val);
break;
case 'amount':
case 'tax':
case 'total':
return floatval($val);
break;
default :
//mysql_real_escape_string is better
if($oper=='bw' || $oper=='bn') return "'" . addslashes($val) . "%'";
else if ($oper=='ew' || $oper=='en') return "'%" . addcslashes($val) . "'";
else if ($oper=='cn' || $oper=='nc') return "'%" . addslashes($val) . "%'";
else return "'" . addslashes($val) . "'";
}
}
$result = mysql_query("SELECT COUNT(*) AS count FROM invheader a, clients b WHERE a.client_id=b.client_id".$wh);
$row = mysql_fetch_array($result,MYSQL_ASSOC);
$count = $row['count'];
if( $count >0 ) {
$total_pages = ceil($count/$limit);
} else {
$total_pages = 0;
}
if ($page > $total_pages) $page=$total_pages;
$start = $limit*$page - $limit; // do not put $limit*($page - 1)
if ($start<0) $start = 0;
$SQL = "SELECT a.id, a.invdate, b.name, a.amount,a.tax,a.total,a.note FROM invheader a, clients b WHERE a.client_id=b.client_id".$wh." ORDER BY ".$sidx." ".$sord. " LIMIT ".$start." , ".$limit;
$result = mysql_query( $SQL ) or die("Could not execute query.".mysql_error());
$responce->page = $page;
$responce->total = $total_pages;
$responce->records = $count;
$i=0;
while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
$responce->rows[$i]['id']=$row[id];
$responce->rows[$i]['cell']=array($row[id],$row[invdate],$row[name],$row[amount],$row[tax],$row[total],$row[note]);
$i++;
}
//echo $json->encode($responce); // coment if php 5
echo json_encode($responce);
I actually just had this same problem myself yesterday. You are correct, you need to bring in the filters using $_REQUEST['filters'] and then break it up so that you can use each piece.
First, you are going to need to set stringResult: true in your jQuery file where you initialize the FilterToolbar.
Here is the code that PHP will use to bring in, and break up the filters object:
// Gets the 'filters' object from JSON
$filterResultsJSON = json_decode($_REQUEST['filters']);
// Converts the 'filters' object into a workable Array
$filterArray = get_object_vars($filterResultsJSON);
Now that you have $filterArray containing the contents of the filters object, you can now break up the rules object which is contained inside. Basically, there is another array inside the $filterArray which contains the search details if the user tries performing this search across multiple columns in their table - it's called rules.
Here is how I break up the rules object and perform a SELECT query based on the user's input:
// Begin the select statement by selecting cols from tbl
$sql = 'select '.implode(',',$crudColumns).' from '.$crudTableName;
// Init counter to 0
$counter = 0;
// Loop through the $filterArray until we process each 'rule' array inside
while($counter < count($filterArray['rules']))
{
// Convert the each 'rules' object into a workable Array
$filterRules = get_object_vars($filterArray['rules'][$counter]);
// If this is the first pass, start with the WHERE clause
if($counter == 0){
$sql .= ' WHERE ' . $filterRules['field'] . ' LIKE "%' . $filterRules['data'] . '%"';
}
// If this is the second or > pass, use AND
else {
$sql .= ' AND ' . $filterRules['field'] . ' LIKE "%' . $filterRules['data'] . '%"';
}
$counter++;
}
// Finish off the select statement
$sql .= ' ORDER BY ' . $postConfig['sortColumn'] . ' ' . $postConfig['sortOrder'];
$sql .= ' LIMIT '.$intStart.','.$intLimit;
/* run the query */
$result = mysql_query( $sql )
I'm sure you'll have questions, so feel free to ask if you do!
Related
PHP experience system // simple
As a begginer in php programming language i'm playing with the code, working on localhost and i did some little projects.Now i am trying to do an experience system as simple as i can, i am stuck at this part and i don't know what i am doing wrong.Some suggestions? What i am doing wrong? The code. function update_user_xp($user_id, $xp_ammount){ global $db; $params = array('user_id' => $user_id); $users = $db->rawQuery("SELECT * FROM users_xp WHERE user_id = ?", $params); $data = array( 'user_xp_amount' => $xp_ammount + $users[0]['user_xp_amount'], 'user_id' => $user_id ); $db->where ('user_id', $data['user_id']); if ($db->update ('users_xp', $data)){ $xpReceived = 'You have received '.$xp_ammount.' points of experience! Have a total of '.$data['user_xp_amount'].' points of experience.'; } else { $xpReceived = $db->getLastError(); } return $xpReceived; } //update_user_xp(4, 10); // user_id: 4, update with 10 points function get_user_xp ($user_id){ global $db; $params = array('user_id' => $user_id); $user = $db->rawQueryOne ('SELECT * FROM users_xp WHERE user_id=?', $params); $xp = $user['user_xp_amount']; return $xp; } function xp_need () { global $db; $xpBarNeed = $db->rawQuery("SELECT `level`, `expneeded` FROM `experience_level`"); foreach ($xpBarNeed as $key => $value) { $output[] = $value; } return $output; } $xpn = xp_need(); $userXP = get_user_xp(4); for($i = 0; $i < count($xpn); $i++){ if($xpn[$i]['expneeded'] == $userXP) { //This part is working well print 'You are level <b>' . $xpn[$i]['level'].'</b>'; } else { if ($userXP > $xpn[$i]['expneeded'] && $userXP >= $xpn[$i]['expneeded']) { //This is the part that doesn t work, $diffEXP = $xpn[$i]['expneeded'] -= $userXP; print 'You need more exp '. $diffEXP.'</br>'; } } } This is how i am seeing in the page. https://prnt.sc/u7z18u
Please note that my solution is not the best or say a well-optimized solution at the time of writing. I will try to optimize it in the near future. For the time being, you can use this: <?php $xpn = xp_need(); $userXP = get_user_xp(4); $level = 0; $nextExp = 0; for ($i = count($xpn) - 1;$i >= 0;$i--) { if ($userXP >= $xpn[$i]['expneeded']) { $level = $xpn[$i]['level']; $nextExp = $xpn[$i + 1]['expneeded']; break; } } $expNeeded = $nextExp - $userXP; $percentage = round(($userXP/$nextExp) * 100); echo "Current level: " . $level; echo "<br/>Exp needed for the next level (" . ($level + 1) . "): " . $expNeeded; echo "<br/>Exp achieved percentage for the next level: " . $percentage; ?>
PHP Random Name instead of sequence
I have a basic URL shortener script but I am having an issue. Each time I enter a new url to shorten the script just adds the next letter to the database (i.e. http://www.both.com/a then http://www.both.com/b then http://www.both.com/c etc). The problem is I don't want to people to be able to view those links by simply going in sequential order. How can I make it so each new url has a random 6 digit alpha and numerical name created? Also, I wanted to make the alpha both random upper and lower case. <?php require 'config.php'; header('Content-Type: text/plain;charset=UTF-8'); $url = isset($_GET['url']) ? urldecode(trim($_GET['url'])) : ''; if (in_array($url, array('', 'about:blank', 'undefined', 'http://localhost/'))) { die('Enter a URL.'); } if (strpos($url, SHORT_URL) === 0) { die($url); } function nextLetter(&$str) { $str = ('z' == $str ? 'a' : ++$str); } function getNextShortURL($s) { $a = str_split($s); $c = count($a); if (preg_match('/^z*$/', $s)) { // string consists entirely of `z` return str_repeat('a', $c + 1); } while ('z' == $a[--$c]) { nextLetter($a[$c]); } nextLetter($a[$c]); return implode($a); } $db = new mysqli(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE); $db->set_charset('utf8mb4'); $url = $db->real_escape_string($url); $result = $db->query('SELECT slug FROM redirect WHERE url = "' . $url . '" LIMIT 1'); if ($result && $result->num_rows > 0) { // If there’s already a short URL for this URL die(SHORT_URL . $result->fetch_object()->slug); } else { $result = $db->query('SELECT slug, url FROM redirect ORDER BY date DESC, slug DESC LIMIT 1'); if ($result && $result->num_rows > 0) { $slug = getNextShortURL($result->fetch_object()->slug); if ($db->query('INSERT INTO redirect (slug, url, date, hits) VALUES ("' . $slug . '", "' . $url . '", NOW(), 0)')) { header('HTTP/1.1 201 Created'); echo SHORT_URL . $slug; $db->query('OPTIMIZE TABLE `redirect`'); } } } ?>
try something like this : function generateString($length) { $alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $alphabetLength = strlen($alphabet); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $alphabet[rand(0, $alphabetLength - 1)]; } return $randomString; } $short = generateRandomString(6);
How can I get more than one GET parameter by using switch/case in php?
I'm pretty new to programming and currently working on a video game database thingy. I'm stuck at a point at which I want to filter my entries with the "GET" method. It all works fine until I want to search after multiple parameters for the main issue is to go through my switch/case statement multiple times. So here's the code: $columnName = NULL; $searchValue = NULL; switch ($_GET) { case isset($_GET['name']): $columnName = "games.name"; $searchValue = $_GET['name']; break; case isset($_GET['developer']): $columnName = "developer.name"; $searchValue = $_GET['developer']; break; case isset($_GET['device']): $columnName = "devices.name"; $searchValue = $_GET['device']; break; case isset($_GET['company']): $columnName = "company.name"; $searchValue = $_GET['company']; break; case isset($_GET['medium']): $columnName = "medium.name"; $searchValue = $_GET['medium']; break; default: break; } if ($columnName !== null && $searchValue !== null) { $selectStatement .= " WHERE " . $columnName . " LIKE '%" . $searchValue . "%'"; } The variable $selectStatement is the selection statement for my database entries, but i thought it would not be helpful to post it in it's entirety. Thanks in advance. EDIT: I'm surprised that I got so many answers after just a few minutes, thank you so much! But I tried every single of your answers and none is really working for me. For example, if I search for two parameters now, it only recognizes the last one. In this example http://localhost/index.php?developer=ubisoft&medium=disc it only shows me the medium, but not the developer...
switch is not ideal to use for your case. you can have an IF ELSE condition if ( isset($_GET['name']) ){ $columnName = "games.name"; $searchValue = $_GET['name']; } elseif( isset($_GET['developer']) ) { $columnName = "developer.name"; $searchValue = $_GET['developer']; } elseif(){ } and so on.... Another way is you can have an array to map your parameter to column name. $_GET['type'] --> this can be your name, developer, medium, device, company... $_GET['value'] --> your value for name or developer or medium.... $mapping = [ 'name' => 'games.name', 'developer' => 'developer.name', 'device' => 'device.name', 'medium' => 'medium.name' ]; $columnName = $mapping[$_GET['type']]; $searchValue = $_GET['value']; $selectStatement .= " WHERE " . $columnName . " LIKE '%" . $searchValue . "%'";
You should use if statement for multiple conditions or do not use break statement (not recommended) Working demo with static GET values: https://eval.in/868873 if ($_GET) { if( isset($_GET['name'])) { $columnName[] = "games.name"; $searchValue[] = $_GET['name']; } if( isset($_GET['developer'])) { $columnName[] = "developer.name"; $searchValue[] = $_GET['developer']; } if( isset($_GET['device'])) { $columnName[] = "devices.name"; $searchValue[] = $_GET['device']; } if( isset($_GET['company'])) { $columnName[] = "company.name"; $searchValue[] = $_GET['company']; } if( isset($_GET['medium'])) { $columnName[] = "medium.name"; $searchValue[] = $_GET['medium']; } } Loop through columnName $selectStatement = ''; if ($columnName !== null && $searchValue !== null) { $length = count($columnName); for ($i=0; $i < $length; $i++) { if ($i == 0) $selectStatement .= " WHERE " . $columnName[$i] . " LIKE '%" . $searchValue[$i] . "%'"; else $selectStatement .= " AND " . $columnName[$i] . " LIKE '%" . $searchValue[$i] . "%'"; } } echo $selectStatement; for ?developer=ubisoft&medium=disc Output: WHERE developer.name LIKE '%ubisoft%' AND medium.name LIKE '%disc%'
why do you use switch/case statement? It is suitable for searching one occurence of element in your elements set. Just use if statement. It would look like following: $columns = array(); if(isset($_GET["column1"])) { $columns []= $_GET["column1"]; } if(isset($_GET["column2"])) { $columns []= $_GET["column2"]; } $columnsString = implode(",", $columns); // You will get string like "column1,column2" // And you can make the same thing with your WHERE statements
Warning: Missing argument 2 for feed::getLikes(), called in [...]on line 1497 and defined in [...] on line 3117
There are errors in the lines I mentioned, but I could not figure out what it is. There is something illogical in this line, but I did not see. I mentioned the line is a range of places. Line: 1497 '.(($this->getLikes()) ? '<div class="sidebar-list">'.$LNG['likes'].': <strong>'.$this->getLikes().' '.$LNG['messages'].'</strong></div>' : '').' Line: 3117 function getLikes($start, $type) { global $LNG; // Type 0: Return the likes count // Type 1: Return the liked posts if($type) { if($start == 0) { $start = ''; } else { $start = 'AND `likes`.`id` < \''.$this->db->real_escape_string($start).'\''; } $query = sprintf("SELECT `likes`.`id` as `like_id`, `likes`.`post` as `like_post`, `likes`.`by` as `like_by`, `likes`.`time` as `time`, `messages`.`id` as `id`, `messages`.`message` as `message`, `messages`.`type` as `type`, `messages`.`value` as `value`, `users`.`username` as `username`, `users`.`first_name` as `first_name`, `users`.`last_name` as `last_name`, `users`.`image` as `image` FROM `likes`,`messages`,`users` WHERE `likes`.`by` = '%s' AND `likes`.`post` = `messages`.`id` AND `messages`.`uid` = `users`.`idu` AND `messages`.`public` = 1 %s ORDER BY `likes`.`time` DESC LIMIT %s", $this->profile_data['idu'], $start, ($this->per_page + 1)); $getLikes = $this->db->query($query); // Declare the rows array $rows = array(); while($row = $getLikes->fetch_assoc()) { // Store the result into the array $rows[] = $row; } // Decide whether the load more will be shown or not if(array_key_exists($this->per_page, $rows)) { $loadmore = 1; // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed array_pop($rows); } // Start the output foreach($rows as $value) { $time = $value['time']; $b = ''; if($this->time == '0') { $time = date("c", strtotime($value['time'])); } elseif($this->time == '2') { $time = $this->ago(strtotime($value['time'])); } elseif($this->time == '3') { $date = strtotime($value['time']); $time = date('Y-m-d', $date); $b = '-standard'; } $output .= '<div class="message-container"><div class="message-content"><div class="message-inner"> '.realName($this->profile_data['username'], $this->profile_data['first_name'], $this->profile_data['last_name']).' '.sprintf($LNG['x_liked_y_post'], '<div class="like_btn like_btn_extended" style="float: none;"><img src="'.$this->url.'/thumb.php?src='.$value['image'].'&w=25&h=25&t=a" /></div>'.realName($value['username'], $value['first_name'], $value['last_name']).'', $this->url.'/index.php?a=post&m='.$value['like_post']).' - <span class="timeago'.$b.'" title="'.$time.'" style="float: none;">'.$time.'</span> '.((!empty($value['message'])) ? '<div class="like_text_snippet">'.($this->parseMessage(substr($value['message'], 0, 60))).'...</div>' : '').'</div></div></div>'; } // Display the load more button if($loadmore) { $output .= '<div class="message-container" id="more_messages"> <div class="load_more"><a onclick="loadLikes('.$value['like_id'].', \''.$this->profile_data['idu'].'\', \''.$this->profile_data['username'].'\')">'.$LNG['view_more_messages'].'</a></div> </div>'; } return $output; } else { $query = $this->db->query(sprintf("SELECT count(`likes`.`id`) FROM `likes`,`messages` WHERE `likes`.`by` = '%s' AND `likes`.`post` = `messages`.`id` AND `messages`.`public` = '1'", $this->profile_data['idu'])); // Store the array results $result = $query->fetch_array(); // Return the likes value return $result[0]; } }
The message is clear enough. In definition of function you have: getLikes($start, $type) so you need to always pass 2 parameters to the function Instead of '.(($this->getLikes()) ? '<div class="sidebar-list">'.$LNG['likes'].': <strong>'.$this->getLikes().' '.$LNG['messages'].'</strong></div>' : '').' you should have something like that: '.(($this->getLikes($something1, $something2)) ? '<div class="sidebar-list">'.$LNG['likes'].': <strong>'.$this->getLikes($something1, $something2).' '.$LNG['messages'].'</strong></div>' : '').'
Add a number after a string, if it already exists
I'm working on a script that checks if the url already exists in the database, and if yes adds an additional -1 or -2 etc etc at the end. I found this script But it 'd need to to check it again after adding-1. Since it may be already existing. How can I do that? I tired i this way $query = mysql_query("SELECT * FROM posts WHERE url='$url'"); while ( $query ) { $result = mysql_fetch_assoc($query); $url = $result['url']; $urlnew = $result['url']; $oldurl = $url; $first = 1; $separator = '-'; while ( $urlnew == $url ) { $url = preg_match('/(.+)'.$separator.'([0-9]+)$/', $urlnew, $match); $urlnew = isset($match[2]) ? $match[1].$separator.($match[2] + 1) : $url.$separator.$first; $first++; } $url = $urlnew; } The new code above works just fine. But it checks only once. How can I make it to check untill it dose not exists in the DB? tried adding a new sql query at the bottom after $url -$urlnew but it only breaks the function. EDIT Here's the correct script :D $query = mysql_query("SELECT * FROM posts WHERE url LIKE '%".$url."%'"); if ( $query ) { while ( $result = mysql_fetch_assoc($query) ) { $url = $result['url']; $urlnew = $result['url']; $first = 1; $separator = '-'; while ( $urlnew == $url ) { preg_match('/(.+)'.$separator.'([0-9]+)$/', $urlnew, $match); $urlnew = isset($match[2]) ? $match[1].$separator.($match[2] + 1) :$url.$separator.$first; $first++; } } } $url = $urlnew;
Your code is likely vulnerable to SQL Injection. You should consider using PDO or MySQLi instead. Here's an example of how you could do so: $url = 'www.example.com'; $i = 0; $max_duplicates = 100; $query = $pdo->prepare('SELECT COUNT(id) count FROM urls WHERE url=?'); while ($i++ < $max_duplicates) { $result = $query->execute($url); if (!$result->fetch(PDO::FETCH_OBJ)->count) break; if ($i == 1) { $url = $url . '-1'; } else { $n = $i > 10 ? 2 : 1; $url = substr($url, -$n) . $i; } }
Here's what I used for my needs function checkLink($link, $counter=1){ global $connect; $newLink = $link; do{ $checkLink = mysqli_query($connect, "SELECT id FROM table WHERE link = '$newLink'"); if(mysqli_num_rows($checkLink) > 0){ $newLink = $link.'-'.$counter; $counter++; } else { break; } } while(1); return $newLink; } $link = 'www.example.com'; $uniquelink = checkLink($link);