if name exists save as name(1) name(2) and so on - php

There's a mysql database that stores ids and names, when users are creating names with a form they can create existent names since unique ids are the ids such as:
d49f2c32f9107c87c7bb7b44f1c8f297 name
2fa9c810fbe082900975f827e8ed9408 name
what i want to do is saving the second "name" -> "name(1)" when inserting into database.
So far what I've got is this as the idea
lets say the name entered is 'name'
$input = 'name';
select the name we want to check from mysql database
mysql_query(SELECT * FROM `table` WHERE `name` = '$input');
if the result exists, then insert as $input.'(1)'
my question is what if name exists, and name(1) also exists, then how can i add the name(2) there...

You could return the number of people with that name in the database, then add 1 to that number.
SELECT COUNT(id) FROM table WHERE name LIKE '$input(%)');

$i = 1;
$sourceName = $name;
while( sql "SELECT COUNT(*) FROM table WHERE name = '$name'" ) {
$name = $sourceName.' ('.$i.')';
$i++;
}
At this point you have the final $name (with $i counting the iteration)

Something like this should do the trick:
SELECT * FROM table WHERE name = '$input' OR name LIKE '$input(%)'
Note that for this to work, you'd need to escape any percent signs in $input in the LIKE clause, otherwise they'll be treated as wildcards.

Use a regex that checks for integers between two parentheses at the end of the string. If there exists an integer, add 1 to it.

You could also attempt to do it the other way around, make name field unique and try to input it in a while loop, if it fails add ($i) and do $i++ every iteration.
//edit:
The problem with using solutions that do a like comparison is that you will get false positives, for instance $hi% will also count hippie. Which gives you unnecessary (1) additions!

Related

use PHP variable in MySQL REGEXP

I have multiple ids separated by + in one field of a row in a table
Like : (123+21654+412+12387)
I need Only EXACT MATCHES, (e.g.: only "123" and not "123 & 12387")
My code is like this:
$var = $value['id'];
$result = mysqli_query($this->dbh, "SELECT id FROM table
WHERE id REGEXP '[[:<:]]$var[[:>:]]' ");
I have a problem with using a variable in REGEXP.
in case of :
$result = mysqli_query($this->dbh, "Select id FROM table
WHERE id REGEXP '^$id|[\+]$id' ");
it works, but it does not return only exact matches
PHP tip: "Interpolation" works these ways:
"...$var[...]..." treats that as an array lookup for $var[...].
Without [, $var is assumed to be a scalar.
"...{$var}[...]..." is what you need
This last example has braces {} to tell PHP to evaluate what is inside without being concerned about what follows. More common usage:
$var = 'abc';
// I want to generate "abc123"
$bad = "$var123"; // looks for variable 'var123'
$good = "{$var}123; // correctly yields "abc123"
Your second attempt can be fixed thus:
REGEXP '(^|\+)$id(\+|$)'
meaning:
At the beginning or after a +,
Find $id (after interpolating),
And stop with a + or the end of the string.
I'll go with :
$sql = "SELECT id FROM table WHERE id='123' OR id LIKE '123+%' OR id LIKE '%+123' OR id LIKE '%+123+%'";
The first condition will apply if you only have the value, the second if the field starts with the value, the third if the field ends with the value and the fourth if the value is in the middle of the field.

Increment varchar values on duplicate entry

I know that varchar type of columns are not incrementable, but I want to do something like this:
When a duplicated value is inserted, the new one will be tagged with a number at the end.
For example, we have post-name on our column in the database. Another value post-name is entered, so the next is going to be post-name-2, followed by post-name-3.
I have programmed something in php but its not very convenient.
$post_url_ = $post_url." %";
$stmt_check1 = $this->conn->prepare("SELECT * FROM post WHERE post_url LIKE :post_url ");
$stmt_check2 = $this->conn->prepare("SELECT * FROM post WHERE post_url = :post_url ");
$stmt_check1->bindparam(":post_url",$post_url_);
$stmt_check2->bindparam(":post_url",$post_url);
$stmt_check1->execute();
$stmt_check2->execute();
$rows1 = $stmt_check1->rowCount();
$rows2 = $stmt_check2->rowCount();
if($rows1<=0 && $rows2==1) {
$repeat_no = $rows1+1;
$post_url = $post_url."-$repeat_no";
}
if($rows1>0){
$repeat_no = $rows1+1;
$post_url = $post_url."-$repeat_no";
}
Instead of trying to create a complicate process to keep the correct name, just add separated field version
Then for UI proporse just concatenate both
SELECT CONCAT(post , '-', version)
You can use do...while loop to check next numbers. It isn't performance problem, becuase you will use that only on save new record.
Before loop, create counter (initial by 0).
In loop - if counter > 0, add number to end of url
Increase counter
Check if url exists in database (while results from db > 0)

Compare integer inside url in database

I have the following rows in the database inside url column:
http://some_url/something/34123122.json
http://some_url/something/53124322.json
http://some_url/something/22214322.json
And I want to retrieve them in some function, like this (pseudocode):
function retrieve($ids) {
return $this->fetchAll("SELECT * FROM table WHERE url IN $ids");
}
The problem is that $ids parameter MUST BE an array with ids from those urls only, like:
array(
[0] => 34123122
[1] => 22214322
)
So I have to do something in this function so that I can retrieve rows with urls that contain those ids. How can I do that? Urls can change, but the /******.json ending has always the same pattern.
I don't want to make another query selecting the beginning of the url, it will slow down the application too much.
The proper way to do this is to query only the part of the data that you are interested in - the number. So, you receive an instant +10 to intelligence from performing a quest nearby and you determine that you could create another column to save that number. Your table looks like this now:
CREATE TABLE mytable (
id int not null auto_increment,
url varchar(255) not null,
json_number int not null,
PRIMARY KEY(id),
INDEX(json_number)
) ENGINE = InnoDB;
Before inserting into the table, you use integer sanitizing filter to extract the number from the URL without wasting too much time
Given a URL like this: http://some_url/something/34123122.json you can easily extract the number like this:
$url = 'http://some_url/something/34123122.json';
$number = filter_var($url, FILTER_SANITIZE_NUMBER_INT);
echo $number; // echoes 34123122
And now your query is trivial, you check the json_number column which is also indexed at the same time.
Naturally, you can ignore all I wrote and try other answers which are ugly hacks and worst of all - they're all full table scans.
you will have to use regex in mysql, change your function:
function retrieve($ids) {
$regex = '('.implode('|', $ids).').json$';
return $this->fetchAll("SELECT * FROM table WHERE url REGEXP '$regex'");
}
Note: this is not an optimal solution for large tables. I would suggest you to create an id field in your table and if all ids are unique then you can make id a primary key. Also whenever you insert in that table take out the id part from url and insert it into the id field. In that way you can skip regex. If you are willing to create an id field, then you can execute the following query to update your current table id field:
mysql> update your_table_name set id=replace(substring_index(url, '/', -1), '.json', '');
I do not know if this is a neat solution, but it should work.
function getData($ids) {
foreach($ids as $item) {
$str[] = $item . ".json";
}
$where = "";
foreach($str as $item) {
$where .= "url LIKE '%$item' OR ";
}
return substr("SELECT * FROM table WHERE " . $where, 0, -4);
}
$ids = array(34123122, 53124322, 22214322);
echo getData($ids);
Result:
SELECT * FROM table WHERE url LIKE '%34123122.json' OR url LIKE '%53124322.json' OR url LIKE '%22214322.json'
I think this should do it. Of course you have to run the query aswell.

Check if username exists, if so, increment by one

When a username is inserted into my database, such as:
John_Smith
I need to check if there is already a John_Smith present. If so, increment it by 1 to become John_Smith_1
So if the following usernames already exist:
John_Smith
John_Smith_1
John_Smith_2
John_Smith_3
....up to John_Smith_10
I need the next John_Smith inserted to be incremented to John_Smith_11.
So far, I have searched and come up with this:
$preferredname= "John_Smith"
//check for duplicate user names
$duplicate= check_for_duplicate_username($preferredname);
//if duplicate, increment the preferredname
if ($duplicate)
{
$parts = explode("_",$preferredname);
if (isset($parts[1]))
$preferredname = $parts[0]."_".$parts[1]."_".($parts[2]+1);
else $preferredname = $parts[0]."_".$parts[1]."_1";
}
This, I believe would work for only the first matching usernames. My problem is checking the database for the version of the name with the highest number.. This is my sql:
function check_for_duplicate_username($name)
{
// check if username already exists
$sql = "SELECT * FROM users WHERE user_username=$name";
//then return duplicates
You can use this query:
$sql = 'SELECT * FROM users WHERE user_username LIKE ' . $name . '_%';
the above will query for rows in which user_username have value similar to John_Smith_* ( where * is any valid character including number, which you have to check later )
you can use this php statement for getting user's suffix number:
preg_match( '/([0-9]+)$/', 'John_smith_10', $matches );
$user_number = $matches[0];
While this may not be the best solution in the grand scheme of things, here is an answer that addresses what you were specifically trying to do. The following query returns the number of users with either $name or $name_123 SELECT COUNT(*) FROM users WHERE user_username REGEXP '$name[_0-9]*$'; So if the value is 0 you can simply use $name by itself, otherwise you can use $name."_". + the number returned by the query.
But as many people have mentioned, prly not the best idea to autoassign usernames (very web 1.0 :P ). I'd recommend email addresses. Another option is to use whatever userid the social app uses along with another field identifying the social app (if you have multiple), and then using an autoincremented id field as the unique primary key..
I had a similar problem I was trying to solve today and did it like this. In my case I needed to store/create a unique directory name based on the users first initial/last name:
$username = "bjones";
$usersql = "SELECT * FROM users WHERE username LIKE '$username%'";
$usercnt = mysqli_num_rows(mysqli_query($con,$usersql));
// If bjones, bjones1, bjones2, etc already exists
if ($usercnt >= 1) {
$num = ++$usercnt; // Increment $usercnt by 1
$username = $username . $num; // Add number to username
}
Assuming bjones, bjones1, bjones2 already exists, I would end up with bjones3.

Check name is unique if not append

My application requires the user to enter their business name, which the application will automatically create into a unique identifier to be used in URLs, ie
"Bob's Cafe" will become "bobs-cafe"
But if there are duplicate names I would like the application to add a number so if there is already a "bobs-cafe" we will use "bobs-cafe-1" and likewise if there is already a "bobs-cafe-1" we will use "bobs-cafe-2"
Ive used explode and also looked at a regular expressions but I dont know the best way to approach this.
Im stuck in being able to grab the number and incrementing it and returning the string
Adding to Sarfraz's answer, you might want to find it using a LIKE statement
SELECT `urlIdentifier` FROM `businesses` WHERE `urlIdentifier` LIKE `bobs-cafe%`
which will get all the bobs-cafe items - that way, if you get 5 rows you know you have
bobs-cafe
bobs-cafe-1
bobs-cafe-2
bobs-cafe-3
bobs-cafe-4
and that you'll need to add bobs-cafe-5
EDIT - Or this:
SELECT count(*) as `howMany` FROM `businesses` WHERE `urlIdentifier` LIKE `bobs-cafe%`
Now your result object ( or array ) will have the total number:
echo $resultObject->howMany; // number of bobs-cafe sql found
Why not to add an autoincrement number to every identifier in the URL?
Just like SO does:
stackoverflow.com/questions/2895334/php-application-check-name-is-unique-if-not-append
so, you have both unique identifier and a business name.
This is even better because they are free to change their business name, without changing an identifier.
As for your question it's very simple. Just for the PHP practice:
if (/* you've found the name is already non unique and have the max one in the $id */) {
$parts = explode("-",$id);
if (isset($parts[1])) $newid = $parts[0]."-".($parts[1]+1);
else $newid = $parts[0]."-1";
}
Assuming $user is already in the form bobs-cafe
function username_exists ( $user ) {
$result = mysql_query("SELECT name FROM table WHERE $name LIKE '$user%' ");
$count = mysql_num_rows($result);
if ( $result ) {
$num = $count+1;
return username_exists ( $user.'-'.$num ) ;
} else {
return $user;
}
}

Categories