Related
I want to shorten long integers in PHP to a string in the same way as how hexadecimal works. I think Google also use this for there sort urls in YouTube.
I have a string of numbers and letters that i want to use:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
where:
8 = 8
a = 10
f = 15
Z = 61
10 = 62
11 = 63
1a = 72
and zo on...
the purpose is to set an integer the sortest way in a parameter in an affiliate url subid for tracking.
I was looking for a good name to discripe my question i find out that there is a sexagesimal numeral system that uses sixty as its base.
Here you can find a function that is shorten urls and avoid fonfusion between similar characters like 0/o and i/1/l/L etc.
<?php
/**
* A pure PHP implementation of NewBase60. A base 60 numbering system designed for
* use with URL shortening. Limited/overlapping character set to avoid confusion
* between similar characters, eg o/0, i/l, etc.
*
* Q: Why not use PHP base_convert()?
* A: Because it only goes up to base 36, and doesn't support the NewBase60
*
* #see http://tantek.pbworks.com/w/page/19402946/NewBase60
* #see http://en.wikipedia.org/wiki/sexagesimal
*
* #author david#dsingleton.co.uk
*/
class NewBase60
{
protected static $characterSet = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz';
/**
* Convert a sexagesimal number to a decimal number
* #param string sexagesimal number to convert
* #return integer Decimal representation of sexagesimal number
*/
public static function toDecimal($sexNum)
{
// Return falsy and 0 values as is
if (!$sexNum) {
return $sexNum === '0' ? 0 : $sexNum;
}
$decNum = 0;
foreach(str_split($sexNum) as $chr) {
$ord = ord($chr);
if ($ord>=48 && $ord<=57) { $ord -= 48; } // 0 - 9
elseif ($ord>=65 && $ord<=72) { $ord -= 55; } // A - H
elseif ($ord==73 || $ord==108) { $ord = 1; } // Error correct typo: capital I, lowercase l to 1
elseif ($ord>=74 && $ord<=78) { $ord -= 56; } // J - N
elseif ($ord==79) { $ord = 0; } // Error correct typo: capital O to 0
elseif ($ord>=80 && $ord<=90) { $ord -= 57; } // P - Z
elseif ($ord==95) { $ord = 34; } // underscore
elseif ($ord>=97 && $ord<=107) { $ord -= 62; } // a - k
elseif ($ord>=109 && $ord<=122) { $ord -= 63; } // m - z
else { $ord = 0; } // treat all other noise as 0
$decNum = 60 *$decNum + $ord;
}
return $decNum;
}
/**
* Convert a decimal number to a sexagesimal number
* #param integer Decimal number to convert
* #return string sexagesimal representation of decimal
*/
public static function fromDecimal($decNum)
{
$decNum = (int) $decNum;
if (!$decNum) {
return $decNum === 0 ? '0' : $sexNum;
}
$aSexCharset = self::$characterSet;
$result = '';
while ($decNum > 0) {
$decRemainder = $decNum % 60;
$decNum = ($decNum - $decRemainder) / 60;
$result = $aSexCharset[$decRemainder] . $result;
}
return $result;
}
}
Copyright: https://github.com/dsingleton/new-base-60/blob/master/newbase60.class.php
Since i'm more of a "noob" at PHP than i'd hope, Is it possible to inverse the following function for example:
public function baseID($resourceid){
$rid = $resourceid;
$version = 0;
while ($rid > 16777216){
$version++;
if ($version == 1){
//the constant applied to all items
$rid -= 1342177280;
}elseif ($version == 2){
//the value added to the first updated version
$rid -= 50331648;
}else{
//the value added on all subsequent versions
$rid -= 16777216;
}
}
//$returnable = array('baseID'=>$rid,'version'=>$version);
return $rid;
}
Would it be possible to input the "baseID" and return a "resourceID" instead of the current way ?
I apologize if this is the wrong place to be asking such question
Not really. Your function returns the same value for all rids that are of the form:
5 * 2^28 + (3 + n) * 2^24
Where n is a positive integer.
>>> baseID(5 * 2**28 + (3 + 1) * 2**24)
16777216
>>> baseID(5 * 2**28 + (3 + 2) * 2**24)
16777216
>>> baseID(5 * 2**28 + (3 + 3) * 2**24)
16777216
So given just 16777216, you won't be able to determine what went into your function.
This function only works to a limited range, however at a certain point the resource IDs will start returning the same results.
public function resourceID($baseid){
$bid = $baseid;
$version = 0;
while ($bid <= 16777216){
++$version;
if ($version === 1){
$bid += 1342177280;
} elseif ($version === 2){
$bid += 50331648;
} else {
$bid += 16777216;
}
}
return $bid;
}
The function levenshtein in PHP works on strings with maximum length 255. What are good alternatives to compute a similarity score of sentences in PHP.
Basically I have a database of sentences, and I want to find approximate duplicates.
similar_text function is not giving me expected results. What is the easiest way for me to detect similar sentences like below:
$ss="Jack is a very nice boy, isn't he?";
$pp="jack is a very nice boy is he";
$ss=strtolower($ss); // convert to lower case as we dont care about case
$pp=strtolower($pp);
$score=similar_text($ss, $pp);
echo "$score %\n"; // Outputs just 29 %
$score=levenshtein ( $ss, $pp );
echo "$score\n"; // Outputs '5', which indicates they are very similar. But, it does not work for more than 255 chars :(
The levenshtein algorithm has a time complexity of O(n*m), where n and m are the lengths of the two input strings. This is pretty expensive and computing such a distance for long strings will take a long time.
For whole sentences, you might want to use a diff algorithm instead, see for example: Highlight the difference between two strings in PHP
Having said this, PHP also provides the similar_text function which has an even worse complexity (O(max(n,m)**3)) but seems to work on longer strings.
I've found the Smith Waterman Gotoh to be the best algorithm for comparing sentences. More info in this answer. Here is the PHP code example:
class SmithWatermanGotoh
{
private $gapValue;
private $substitution;
/**
* Constructs a new Smith Waterman metric.
*
* #param gapValue
* a non-positive gap penalty
* #param substitution
* a substitution function
*/
public function __construct($gapValue=-0.5,
$substitution=null)
{
if($gapValue > 0.0) throw new Exception("gapValue must be <= 0");
//if(empty($substitution)) throw new Exception("substitution is required");
if (empty($substitution)) $this->substitution = new SmithWatermanMatchMismatch(1.0, -2.0);
else $this->substitution = $substitution;
$this->gapValue = $gapValue;
}
public function compare($a, $b)
{
if (empty($a) && empty($b)) {
return 1.0;
}
if (empty($a) || empty($b)) {
return 0.0;
}
$maxDistance = min(mb_strlen($a), mb_strlen($b))
* max($this->substitution->max(), $this->gapValue);
return $this->smithWatermanGotoh($a, $b) / $maxDistance;
}
private function smithWatermanGotoh($s, $t)
{
$v0 = [];
$v1 = [];
$t_len = mb_strlen($t);
$max = $v0[0] = max(0, $this->gapValue, $this->substitution->compare($s, 0, $t, 0));
for ($j = 1; $j < $t_len; $j++) {
$v0[$j] = max(0, $v0[$j - 1] + $this->gapValue,
$this->substitution->compare($s, 0, $t, $j));
$max = max($max, $v0[$j]);
}
// Find max
for ($i = 1; $i < mb_strlen($s); $i++) {
$v1[0] = max(0, $v0[0] + $this->gapValue, $this->substitution->compare($s, $i, $t, 0));
$max = max($max, $v1[0]);
for ($j = 1; $j < $t_len; $j++) {
$v1[$j] = max(0, $v0[$j] + $this->gapValue, $v1[$j - 1] + $this->gapValue,
$v0[$j - 1] + $this->substitution->compare($s, $i, $t, $j));
$max = max($max, $v1[$j]);
}
for ($j = 0; $j < $t_len; $j++) {
$v0[$j] = $v1[$j];
}
}
return $max;
}
}
class SmithWatermanMatchMismatch
{
private $matchValue;
private $mismatchValue;
/**
* Constructs a new match-mismatch substitution function. When two
* characters are equal a score of <code>matchValue</code> is assigned. In
* case of a mismatch a score of <code>mismatchValue</code>. The
* <code>matchValue</code> must be strictly greater then
* <code>mismatchValue</code>
*
* #param matchValue
* value when characters are equal
* #param mismatchValue
* value when characters are not equal
*/
public function __construct($matchValue, $mismatchValue) {
if($matchValue <= $mismatchValue) throw new Exception("matchValue must be > matchValue");
$this->matchValue = $matchValue;
$this->mismatchValue = $mismatchValue;
}
public function compare($a, $aIndex, $b, $bIndex) {
return ($a[$aIndex] === $b[$bIndex] ? $this->matchValue
: $this->mismatchValue);
}
public function max() {
return $this->matchValue;
}
public function min() {
return $this->mismatchValue;
}
}
$str1 = "Jack is a very nice boy, isn't he?";
$str2 = "jack is a very nice boy is he";
$o = new SmithWatermanGotoh();
echo $o->compare($str1, $str2);
You could try using similar_text.
It can get quite slow with 20,000+ characters (3-5 seconds) but your example you mention using only sentences, this will work just fine for that usage.
One thing to note is when comparing string of different sizes you will not get 100%. For example if you compare "he" with "head" you would only get a 50% match.
How can I check if a given number is within a range of numbers?
The expression:
($min <= $value) && ($value <= $max)
will be true if $value is between $min and $max, inclusively
See the PHP docs for more on comparison operators
You can use filter_var
filter_var(
$yourInteger,
FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => $min,
'max_range' => $max
)
)
);
This will also allow you to specify whether you want to allow octal and hex notation of integers. Note that the function is type-safe. 5.5 is not an integer but a float and will not validate.
Detailed tutorial about filtering data with PHP:
https://phpro.org/tutorials/Filtering-Data-with-PHP.html
Might help:
if ( in_array(2, range(1,7)) ) {
echo 'Number 2 is in range 1-7';
}
http://php.net/manual/en/function.range.php
You could whip up a little helper function to do this:
/**
* Determines if $number is between $min and $max
*
* #param integer $number The number to test
* #param integer $min The minimum value in the range
* #param integer $max The maximum value in the range
* #param boolean $inclusive Whether the range should be inclusive or not
* #return boolean Whether the number was in the range
*/
function in_range($number, $min, $max, $inclusive = FALSE)
{
if (is_int($number) && is_int($min) && is_int($max))
{
return $inclusive
? ($number >= $min && $number <= $max)
: ($number > $min && $number < $max) ;
}
return FALSE;
}
And you would use it like so:
var_dump(in_range(5, 0, 10)); // TRUE
var_dump(in_range(1, 0, 1)); // FALSE
var_dump(in_range(1, 0, 1, TRUE)); // TRUE
var_dump(in_range(11, 0, 10, TRUE)); // FALSE
// etc...
if (($num >= $lower_boundary) && ($num <= $upper_boundary)) {
You may want to adjust the comparison operators if you want the boundary values not to be valid.
You can try the following one-statement:
if (($x-$min)*($x-$max) < 0)
or:
if (max(min($x, $max), $min) == $x)
Some other possibilities:
if (in_array($value, range($min, $max), true)) {
echo "You can be sure that $min <= $value <= $max";
}
Or:
if ($value === min(max($value, $min), $max)) {
echo "You can be sure that $min <= $value <= $max";
}
Actually this is what is use to cast a value which is out of the range to the closest end of it.
$value = min(max($value, $min), $max);
Example
/**
* This is un-sanitized user input.
*/
$posts_per_page = 999;
/**
* Sanitize $posts_per_page.
*/
$posts_per_page = min(max($posts_per_page, 5), 30);
/**
* Use.
*/
var_dump($posts_per_page); // Output: int(30)
using a switch case
switch ($num){
case ($num>= $value1 && $num<= $value2):
echo "within range 1";
break;
case ($num>= $value3 && $num<= $value4):
echo "within range 2";
break;
.
.
.
.
.
default: //default
echo "within no range";
break;
}
I've created a simple helper function.
if ( !function_exists('number_between') )
{
/**
* number_between
*
* #param {integer} $number
* #param {array} $range [min, max]
* #return {boolean}
*/
function number_between(
int $number,
array $range
){
if(
count($range) !== 2 ||
is_numeric($range[0]) === FALSE ||
is_numeric($range[1]) === FALSE
){
throw new \Exception("number_between second parameter must contain two numbers.", E_WARNING);
}
if(
in_array($number, range($range[0], $range[1]))
){
return TRUE;
}else{
return FALSE;
}
}
}
Another way to do this with simple if/else range. For ex:
$watermarkSize = 0;
if (($originalImageWidth >= 0) && ($originalImageWidth <= 640)) {
$watermarkSize = 10;
} else if (($originalImageWidth >= 641) && ($originalImageWidth <= 1024)) {
$watermarkSize = 25;
} else if (($originalImageWidth >= 1025) && ($originalImageWidth <= 2048)) {
$watermarkSize = 50;
} else if (($originalImageWidth >= 2049) && ($originalImageWidth <= 4096)) {
$watermarkSize = 100;
} else {
$watermarkSize = 200;
}
I created a function to check if times in an array overlap somehow:
/**
* Function to check if there are overlapping times in an array of \DateTime objects.
*
* #param $ranges
*
* #return \DateTime[]|bool
*/
public function timesOverlap($ranges) {
foreach ($ranges as $k1 => $t1) {
foreach ($ranges as $k2 => $t2) {
if ($k1 != $k2) {
/* #var \DateTime[] $t1 */
/* #var \DateTime[] $t2 */
$a = $t1[0]->getTimestamp();
$b = $t1[1]->getTimestamp();
$c = $t2[0]->getTimestamp();
$d = $t2[1]->getTimestamp();
if (($c >= $a && $c <= $b) || $d >= $a && $d <= $b) {
return true;
}
}
}
}
return false;
}
Here is my little contribution:
function inRange($number) {
$ranges = [0, 13, 17, 24, 34, 44, 54, 65, 200];
$n = count($ranges);
while($n--){
if( $number > $ranges[$n] )
return $ranges[$n]+1 .'-'. $ranges[$n + 1];
}
I have function for my case
Use:
echo checkRangeNumber(0);
echo checkRangeNumber(1);
echo checkRangeNumber(499);
echo checkRangeNumber(500);
echo checkRangeNumber(501);
echo checkRangeNumber(3001);
echo checkRangeNumber(999);
//return
0
1-500
1-500
1-500
501-1000
3000-3500
501-1000
function checkRangeNumber($number, $per_page = 500)
{
//$per_page = 500; // it's fixed number, but...
if ($number == 0) {
return "0";
}
$num_page = ceil($number / $per_page); // returns 65
$low_limit = ($num_page - 1) * $per_page + 1; // returns 32000
$up_limit = $num_page * $per_page; // returns 40
return "$low_limit-$up_limit";
}
function limit_range($num, $min, $max)
{
// Now limit it
return $num>$max?$max:$num<$min?$min:$num;
}
$min = 0; // Minimum number can be
$max = 4; // Maximum number can be
$num = 10; // Your number
// Number returned is limited to be minimum 0 and maximum 4
echo limit_range($num, $min, $max); // return 4
$num = 2;
echo limit_range($num, $min, $max); // return 2
$num = -1;
echo limit_range($num, $min, $max); // return 0
$ranges = [
1 => [
'min_range' => 0.01,
'max_range' => 199.99
],
2 => [
'min_range' => 200.00,
],
];
foreach($ranges as $value => $range){
if(filter_var($cartTotal, FILTER_VALIDATE_FLOAT, ['options' => $range])){
return $value;
}
}
Thank you so much and I got my answer by adding a break in the foreach loop and now it is working fine.
Here are the updated answer:
foreach ($this->crud->getDataAll('shipping_charges') as $ship) {
if ($weight >= $ship->low && $weight <= $ship->high) {
$val = $ship->amount;
break;
}
else
{
$val = 900;
}
}
echo $val ;
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
The community reviewed whether to reopen this question 10 months ago and left it closed:
Opinion-based Update the question so it can be answered with facts and citations by editing this post.
Improve this question
Is there any way to create unique keys like those used in YouTube video urls (ex: https://www.youtube.com/watch?v=nWChTnkVdKE)?
The idea is to convert a unique integer (such as current time) in an other mathematical base.
A very simple way in PHP :
// With this precision (microsecond) ID will looks like '2di2adajgq6h'
// From PHP 7.4.0 this is needed, otherwise a warning is displayed
$cleanNumber = preg_replace( '/[^0-9]/', '', microtime(false) );
$id = base_convert($cleanNumber, 10, 36);
// With less precision (second) ID will looks like 'niu7pj'
$id = base_convert(time(), 10, 36);
A small PHP class to generate YouTube-like hashes from one or many numbers. Use hashids when you do not want to expose your database ids to the user.
Source: https://github.com/ivanakimov/hashids.php
Use whichever you like :-)
// Generates Alphanumeric Output
function generateRandomID() {
// http://mohnish.in
$required_length = 11;
$limit_one = rand();
$limit_two = rand();
$randomID = substr(uniqid(sha1(crypt(md5(rand(min($limit_one, $limit_two), max($limit_one, $limit_two)))))), 0, $required_length);
return $randomID;
}
// Generates only alphabetic output
function anotherRandomIDGenerator() {
// Copyright: http://snippets.dzone.com/posts/show/3123
$len = 8;
$base='ABCDEFGHKLMNOPQRSTWXYZabcdefghjkmnpqrstwxyz';
$max=strlen($base)-1;
$activatecode='';
mt_srand((double)microtime()*1000000);
while (strlen($activatecode)<$len+1)
$activatecode.=$base{mt_rand(0,$max)};
return $activatecode;
}
For me best algorithm is this: Create Youtube-Like IDs With PHP/Python/Javascript/Java/SQL
<?php
/**
* Translates a number to a short alhanumeric version
*
* Translated any number up to 9007199254740992
* to a shorter version in letters e.g.:
* 9007199254740989 --> PpQXn7COf
*
* specifiying the second argument true, it will
* translate back e.g.:
* PpQXn7COf --> 9007199254740989
*
* this function is based on any2dec && dec2any by
* fragmer[at]mail[dot]ru
* see: http://nl3.php.net/manual/en/function.base-convert.php#52450
*
* If you want the alphaID to be at least 3 letter long, use the
* $pad_up = 3 argument
*
* In most cases this is better than totally random ID generators
* because this can easily avoid duplicate ID's.
* For example if you correlate the alpha ID to an auto incrementing ID
* in your database, you're done.
*
* The reverse is done because it makes it slightly more cryptic,
* but it also makes it easier to spread lots of IDs in different
* directories on your filesystem. Example:
* $part1 = substr($alpha_id,0,1);
* $part2 = substr($alpha_id,1,1);
* $part3 = substr($alpha_id,2,strlen($alpha_id));
* $destindir = "/".$part1."/".$part2."/".$part3;
* // by reversing, directories are more evenly spread out. The
* // first 26 directories already occupy 26 main levels
*
* more info on limitation:
* - http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/165372
*
* if you really need this for bigger numbers you probably have to look
* at things like: http://theserverpages.com/php/manual/en/ref.bc.php
* or: http://theserverpages.com/php/manual/en/ref.gmp.php
* but I haven't really dugg into this. If you have more info on those
* matters feel free to leave a comment.
*
* The following code block can be utilized by PEAR's Testing_DocTest
* <code>
* // Input //
* $number_in = 2188847690240;
* $alpha_in = "SpQXn7Cb";
*
* // Execute //
* $alpha_out = alphaID($number_in, false, 8);
* $number_out = alphaID($alpha_in, true, 8);
*
* if ($number_in != $number_out) {
* echo "Conversion failure, ".$alpha_in." returns ".$number_out." instead of the ";
* echo "desired: ".$number_in."\n";
* }
* if ($alpha_in != $alpha_out) {
* echo "Conversion failure, ".$number_in." returns ".$alpha_out." instead of the ";
* echo "desired: ".$alpha_in."\n";
* }
*
* // Show //
* echo $number_out." => ".$alpha_out."\n";
* echo $alpha_in." => ".$number_out."\n";
* echo alphaID(238328, false)." => ".alphaID(alphaID(238328, false), true)."\n";
*
* // expects:
* // 2188847690240 => SpQXn7Cb
* // SpQXn7Cb => 2188847690240
* // aaab => 238328
*
* </code>
*
* #author Kevin van Zonneveld <kevin#vanzonneveld.net>
* #author Simon Franz
* #author Deadfish
* #author SK83RJOSH
* #copyright 2008 Kevin van Zonneveld (http://kevin.vanzonneveld.net)
* #license http://www.opensource.org/licenses/bsd-license.php New BSD Licence
* #version SVN: Release: $Id: alphaID.inc.php 344 2009-06-10 17:43:59Z kevin $
* #link http://kevin.vanzonneveld.net/
*
* #param mixed $in String or long input to translate
* #param boolean $to_num Reverses translation when true
* #param mixed $pad_up Number or boolean padds the result up to a specified length
* #param string $pass_key Supplying a password makes it harder to calculate the original ID
*
* #return mixed string or long
*/
function alphaID($in, $to_num = false, $pad_up = false, $pass_key = null)
{
$out = '';
$index = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$base = strlen($index);
if ($pass_key !== null) {
// Although this function's purpose is to just make the
// ID short - and not so much secure,
// with this patch by Simon Franz (http://blog.snaky.org/)
// you can optionally supply a password to make it harder
// to calculate the corresponding numeric ID
for ($n = 0; $n < strlen($index); $n++) {
$i[] = substr($index, $n, 1);
}
$pass_hash = hash('sha256',$pass_key);
$pass_hash = (strlen($pass_hash) < strlen($index) ? hash('sha512', $pass_key) : $pass_hash);
for ($n = 0; $n < strlen($index); $n++) {
$p[] = substr($pass_hash, $n, 1);
}
array_multisort($p, SORT_DESC, $i);
$index = implode($i);
}
if ($to_num) {
// Digital number <<-- alphabet letter code
$len = strlen($in) - 1;
for ($t = $len; $t >= 0; $t--) {
$bcp = bcpow($base, $len - $t);
$out = $out + strpos($index, substr($in, $t, 1)) * $bcp;
}
if (is_numeric($pad_up)) {
$pad_up--;
if ($pad_up > 0) {
$out -= pow($base, $pad_up);
}
}
} else {
// Digital number -->> alphabet letter code
if (is_numeric($pad_up)) {
$pad_up--;
if ($pad_up > 0) {
$in += pow($base, $pad_up);
}
}
for ($t = ($in != 0 ? floor(log($in, $base)) : 0); $t >= 0; $t--) {
$bcp = bcpow($base, $t);
$a = floor($in / $bcp) % $base;
$out = $out . substr($index, $a, 1);
$in = $in - ($a * $bcp);
}
}
return $out;
}
Here is a small function that generates unique key randomly each time. It has very fewer chances to repeat same unique ID.
function uniqueKey($limit = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < $limit; $i++) {
$randstring .= $characters[rand(0, strlen($characters))];
}
return $randstring;
}
I was looking for a very quick and simple solution (that was NOT intended to be secure in any way) that would replicate the actual hash code upon regeneration (unlike PHP's microtime unique id). This one did the trick.
http://php.net/manual/en/book.hash.php
So:
for($i=0;$i<count($myArray);$i++) {
$hashCode = "#".hash('crc32b', $myArray[$i]."-".$i);
}
Yields:
#179507fa
#8e9c5640
#f99b66d6
#67fff375
#10f8c3e3
etc
I won't pretend to know how all the different hash algorithms are used but for non-secure uses (like link #anchors) this is handy.
From comments on here:
<?php
function generateRandStr($length){
$randstr = "";
for($i=0; $i<$length; $i++){
$randnum = mt_rand(0,61);
if($randnum < 10){
$randstr .= chr($randnum+48);
}else if($randnum < 36){
$randstr .= chr($randnum+55);
}else{
$randstr .= chr($randnum+61);
}
}
return $randstr;
}
?>
Simply use:
generateRandStr(10);
Sample output: $%29zon(4f
You can mess around with this function to generate just alphanumeric, or just alphabetic characters.
For most purposes uniqid will suffice, if you need to make sure there's absolutely no clash, more convoluted measures are necessary.
all the methods above are good but make sure you know and not assume the generated string is unique. What I have done in the past is made a recursive function that checks the string against my database and if it is unique it returns the value, otherwise it just runs again. This will hardly happen though depending how long your unique string is. Its just good to know its unique.
<?php
function keygen(){
$chars = "bcdfghjklmnpqrstvwxyz";
$chars .= "BCDFGHJKLMNPQRSTVWXYZ";
$chars .= "0123456789";
while(1){
$key = '';
srand((double)microtime()*1000000);
for($i = 0; $i < 10; $i++){
$key .= substr($chars,(rand()%(strlen($chars))), 1);
}
break;
}
return $key;
}
//echo keygen();
?>