Forum Moderators: coopster & phranque

Message Too Old, No Replies

In case of dupe, add a number to the end

         

csdude55

12:14 am on Dec 22, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I thought I had a nifty little plan to see if a string exists in MySQL, and if it does then just add a number to the end and try it again. This will inevitably be the "key" for users, letting me assign a page like example.com/foo.

But, as if often the case, that got more complicated than intended :-/

For example, I might have these results:

csdude
csdude55
csdude12311955

When I try to insert "csdude" the system would see the match, no problem. But I don't necessarily want it to use "csdude12311956" when "csdude1" is perfectly available.

So this is where I've ended up, and I'd like any feedback on improvements or future problems that you see.

# previously, I've already stripped anything following the first @, converted anything
# not \w to a -, removed repeating -, and stripped opening and trailing -

$_ = 'csdude';

# split letters and dashes from any trailing numbers
($actualName, $append) = /([a-zA-Z-]+)([0-9]*)$/;

# create hash from MySQL results
$hash = $dbh->selectall_hashref("SELECT col FROM table WHERE col REGEXP ?", 'col', undef,

# regex looks for anything beginning with $actualName, then optionally
# followed by numbers to the end
'^' . $actualName . '[0-9]*$'
);

# if $_ isn't in the hash, no need to append anything
if (exists($hash->{$_})) {
my %numList;
$append //= 1;

for $key (keys %{$hash}) {
$numList{$key =~ s#$actualName##r} = 1;
}

# $safety[0] will be the highest number in the list
@safety = sort { $b <=> $a } keys %numList;

while ($append <= $safety[0] && exists($numList{$append})) {
$append++;
}
}

$finalResult = $actualName . $append;

Thoughts?

phranque

1:10 am on Dec 22, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



does it work?

csdude55

4:25 am on Dec 22, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



With preliminary tests, yes. But you know how it goes, before making it live on a site with thousands of people that I swear are trying to break it, I like to have a second set of eyes see if there are any glaring logic errors.

lucy24

4:31 am on Dec 22, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Is there something elsewhere in the code that sets a minimum length? I wouldn't want to see someone signing up as “c” and then everyone starting in letter c gets collapsed into the same person. But otherwise it seems like you're looking for any match of $string against leftstring($string,some number < len($string) and > whatever the minimum is) -- translated, as usual, into perl (of which I don't speak a solitary word).

Does this mean you can't have overlapping names, like lucy24 and lucy2424 (form that actually occurs in one of my email addresses because reasons)?

csdude55

5:37 am on Dec 22, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Is there something elsewhere in the code that sets a minimum length?

No, I've just set a max. And I require at least 1 letter, so I guess there's technically a minimum length of 1. But I don't think that would become a problem. In theory, if someone signed up as "c" and then someone else signed up as "c", that second person would automatically become "c1". And then the next person would be "c2". And so on.

At least, that's what my goal with this script is, anyway.

Does this mean you can't have overlapping names, like lucy24 and lucy2424 (form that actually occurs in one of my email addresses because reasons)?

Correct-ish.

I originally assigned numbers to every user, so you would find their data with:

example.com/12345 (to see their user profile)
example.com/classifieds/12345 (to see their classified ads)
example.com/personals/12345 (to see their personal ad)

and so on. But it's not a memorable link at all, and since I'm redoing everything I wanted to change that to something more like:

example.com/lucy24
example.com/classifieds/lucy24
example.com/personals/lucy24

There could be another user with lucy2424, sure; the strings aren't identical so it would be allowed. But if someone tried to create a second lucy24 then they would become lucy25.

perl (of which I don't speak a solitary word).

I've probably told you this, but I learned Perl before HTML! This would have been '96 or so, and the world was a loooottttt different! LOL I was using Netscape Navigator to build HTML through their WYSIWYG editor, then taught myself Perl by downloading freebie scripts I found online, opening them in Notepad, and just reading and trying to figure it out. I bought an O'Reilly book for beginners, but it was WAY over my head! LOL I'm sure that I still have it around here somewhere, I would never throw a book away :-)

mack

6:06 am on Dec 22, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



This is very similar to a problem I am addressing just now. A blogging app I wrote some time ago has a WYSIWYG editor to create articles. One field is the URL (Type_What_You_want). The problem is if I am adding articles similar to ones I have done in the past there is a chance that sooner or later I will use the same value for the URL. Similarly to you, I do a lookup and if I find a match, I add a number. (MMDD) from Linux time.

One thing I would suggest is looping back to check the new value. Depending on what values you choose to add you might create a modified value, someone then uses the original value and gets presented with the same modified value.

Mack.

csdude55

6:54 pm on Dec 22, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Excellent point, @mack!

I crossed that particular bridge awhile back, too, and ended up using numbers anyway; eg,

example.com/article/type-what-you-want/1234

In Apache I created a rewrite for it to /article/view.php?id=1234, and more or less just ignore the type-what-you-want text. It's pretty and search engines like it (or did, I don't know if they still do), though.

I'm not sure if you can use that, but hopefully it helps :-)

phranque

12:14 am on Dec 23, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



example.com/article/type-what-you-want/1234

In Apache I created a rewrite for it to /article/view.php?id=1234, and more or less just ignore the type-what-you-want text. It's pretty and search engines like it (or did, I don't know if they still do), though.

your view.php script should check the type-what-you-want string in the requested url and make sure it is the expected string for id=1234.
if it isn't, your response should be a 301 redirect to the canonical url.

csdude55

1:14 am on Dec 23, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



In my case, I was just doing it for search engines and really didn't care. While moderating I would often go to example.com/article/-/1234 (just throwing in a -) and not worry about it.

But yeah, mack's needs would probably be different so that's a good point for him.