This question already has answers here:
How to generate a random, unique, alphanumeric string?
(31 answers)
Closed 1 year ago.
I am trying to generate a six character alphanumeric unique code using php. I need to generate 100000 unique codes and push into an array.
So far I have done this
$random_numbers = [];
function random_strings()
{
$str_result ='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
while($i <=100000){
array_push($random_numbers,substr(str_shuffle($str_result),0,6));
$i++;
}
print_r($random_numbers);
}
But my server dies when running this code. Do you have any idea, how it can be generated?
Thank you
I fixed the problem. I was declaring the array outside the function
function random_strings()
{
$random_numbers = [];
$str_result ='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
while($i <=100000){
array_push($random_numbers,substr(str_shuffle($str_result),0,6));
$i++;
}
print_r($random_numbers);
}
To ensure you get unique strings, you can use the random string as the key to the array instead, then loop till the array has the required number of entries. This code allows you to pass the number of values you want as well as it returns the array rather than just printing it...
function random_strings( $count )
{
$random_numbers = [];
$str_result ='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
while( count($random_numbers) < $count ){
$random_numbers[substr(str_shuffle($str_result),0,6)] ='';
}
return array_keys($random_numbers);
}
print_r(random_strings(100000));
Simple two line code for you
$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
echo substr(str_shuffle($permitted_chars), 0, 6)
Function example
$n is count of strings
$length is length of each string
function get_random_string($n, $length = 6){
$res = [];
for($i=0; $i<$n; $i++){
$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$res[] = substr(str_shuffle($permitted_chars), 0, $length);
}
return $res;
}
Final result
var_dump(get_random_string(10000, 6));
Result of function
array(10) {
[0]=>
string(6) "iIrekz"
[1]=>
string(6) "SG4Bki"
[2]=>
string(6) "5VBhMd"
[3]=>
string(6) "ubqcLr"
[4]=>
string(6) "hPUqng"
[5]=>
string(6) "9xfvpB"
[6]=>
string(6) "m3UQb6"
[7]=>
string(6) "E9nK3Z"
[8]=>
string(6) "1D0ob5"
[9]=>
string(6) "uC2koH"
...
}
Generating random numbers doesn't guarantee uniqueness. Since you want it for coupon codes, you want it to be accurate.
function random_strings() {
$random_numbers = [];
while( count( $random_numbers ) != 100000 ) {
$uniqueString = md5( microtime() );
$requiredLengthString = strtoupper( substr( $uniqueString, 0, 6 ) ); // substring would not be unique
$random_numbers[$requiredLengthString] = NULL; // Putting $requiredLengthString as key so same keys would be overwritten, guaranteeing uniqueness.
}
return array_keys( $random_numbers );
}
print_r( random_strings() );
Inline refactoring if you wish to reduce LOC:
function random_strings() {
$random_numbers = [];
while( count( $random_numbers ) != 100000 ) {
$random_numbers[strtoupper( substr( md5( microtime() ), 0, 6 ) )] = NULL; // Putting this string as key so same keys would be overwritten, guaranteeing uniqueness.
}
return array_keys( $random_numbers );
}
print_r( random_strings() );
Related
I have two variables one named $corp_resp:
var_dump($corp_resp)
string(3) "0.3" string(4) "0.35" string(3) "0.4"
Other: $corp_resp_template
var_dump($corp_res_template)ยด
string(3) "0.4" string(3) "0.6" string(3) "0.8"
I want to add and multiply the arrays:
$total = (0.3*0.4)+(0.35*0.6) +(0.4*0.8) => 0,12+0.21+0,32
$total = 0.65
What is the best way to do that?
if both your arrays have the same length you can run something like:
array_sum(array_map(
function($resp, $tpl){ return $resp * $tpl; },
$corp_resp, $corp_res_template));
If the arrays are of unequal length, the tail of the longer array will be evaluated to (number * 0) therefore ignoring them when adding up the final result
Write a function to do it
$corp_resp = array("0.3", "0.35", "0.4");
$corp_res_template = array("0.4", "0.6", "0.8");
function add_products($a1, $a2) {
if (!is_array($a1)) {
throw new Exception("a1 is not an array");
}
if (!is_array($a2)) {
throw new Exception("a2 is not an array");
}
if (sizeof($a1) != sizeof($a2)) {
throw new Exception("Arrays don't have same number of elements");
}
// both params are arrays and have same number of elements!
$count = sizeof($a1);
$multiplied = array();
for($i=0; $i<$count; $i++) {
// we assume that each element is a string representing a floatval so we need to cast as a float before multiplying
$multiplied[$i] = floatval($a1[$i]) * floatval($a2[$i]);
}
return array_sum($multiplied);
}
$val = add_products($corp_resp, $corp_res_template);
var_dump($val);
I have a database with multiple records. It is structured like this:
["data"]=>
array(5) {
[1]=>
[2]=>
array(11) {
[0]=>
string(1) "0"
[1]=>
string(8) "25000000"
[2]=>
string(3) "day"
[3]=>
string(5) "0.00%"
[4]=>
string(9) "404049904"
[5]=>
string(1) "0"
[6]=>
string(5) "0.00%"
[7]=>
string(1) "0"
[8]=>
string(1) "0"
[9]=>
string(1) "0"
[10]=>
string(3) "0.0"
}
I need to fetch the 8th record and I do this by using
public static function($data)
{
$array = [];
$path = $data->data[2];
foreach($path as $key => $item)
if($key > 1)
{
$array[] = [$item->data[8]];
}
return json_encode($array);
}
This foreach takes all the 8th values from the array but I need to display a single number which is the average of all the 8th values. How can I do this?
Once you've got your array containing all your data, simple sum the array and then divide by the size of the array.. something along these lines
$average = (array_sum($array) / count($array));
Of course you may want to check for count($array) being 0;
Because you put your value into a new array, you can not use array_sum to sum the values, so you should store it.
$sum = 0;
foreach($path as $key => $item)
if($key > 1) {
$array[] = [$item->data[8]];
$sum += $item->data[8];
}
}
$avg = ($sum / count($array); //the average
var_dump($avg);
If is it possible, just put it as a value:
$array[] = $item->data[8]; //no wrapping []
In this case, you can use $avg = array_sum($array) / count($array);
if (count($array)>0){
$avg = array_sum($array) / count($array);
}
I would personally do those calculations in the database before the data gets to your PHP script itself. See AVG().
If you can't for some reason use that I would output those values into a flat array and then just calculate the average. So something like :
function getAverage($data) {
$flatArray = array();
foreach ($data as $row) {
if (!empty($row->8)) {
$flatArray[] = $row->8;
}
}
return (array_sum($flatArray)/count($flatArray));
}
EDIT: Moved to Object traversing on the data row, sorry, missed that initially and thought it was an array in all the nests.
Since you have a loop within your static Method; why not do the calculation therein and return it or add it to the JSON Data if You need your Data in JSON Format? Here's what's implied by the above:
public static function getAverageSum($data) {
$array = [];
$path = $data->data[2];
$sumTotal = 0.00; //<== YOU COULD JUST SUM IT DIRECTLY WITHOUT USING AN ARRAY
foreach($path as $key => $item) {
if ($key > 1) {
$array[] = $item->data[8];
$sumTotal += floatval($item->data[8]);
}
}
// IF YOU ARE ONLY INTERESTED IN THE AVERAGE SUM YOU COULD EVEN ADD IT IT TO THE $array AS AN EXTRA KEY
// LIKE SO:
$arrLen = count($array);
$array['avgSum'] = $sumTotal/$arrLen;
// IF YOU NEED YOUR DATA IN JSON... THEN RETURN THE JSON ENCODED DATA WITH SUM AS PART OF THE DATA.
// YOU'D HAVE NO NEED FOR array_sum() SINCE YOU DID YOUR PREP-WORK ALREADY...
return json_encode($array);
// ALTERNATIVELY; IF ALL YOU NEED IS JUST THE AVERAGE SUM; YOU COULD AS WELL DIRECTLY RETURN $sumTotal/$arrLen
return ($sumTotal/$arrLen);
}
I have a plain string like this:
1 //here is a number defines phrase name
09/25/2013 //here is a date
<i>some text goes here</i> //and goes text
2
09/24/2013
text goes on and on
4 //as you can see, the numbers can skip another
09/23/2013
heya i'm a text
I need to create array from this but the numbers that defines phrases must give me the date of that line and return the text when i called it. Like,
$line[4][date] should give me "09/23/2013"
Is that possible, if possible can you explain me how to do this?
$stringExample = "1
09/25/2013
<i>some text goes here</i>
2
09/24/2013
text goes on and on
and on and on
4
09/23/2013
heya i'm a text";
$data = explode("\r\n\r\n", $stringExample);
$line = array();
foreach ($data as $block) {
list($id, $date, $text) = explode("\n", $block, 3);
$index = (int) $id;
$line[$index] = array();
$line[$index]["date"] = trim($date);
$line[$index]["text"] = trim($text);
}
var_dump($line) should output:
array(3) {
[1]=>
array(2) {
["date"]=>
string(10) "09/25/2013"
["text"]=>
string(26) "<i>some text goes here</i>"
}
[2]=>
array(2) {
["date"]=>
string(10) "09/24/2013"
["text"]=>
string(34) "text goes on and on
and on and on"
}
[4]=>
array(2) {
["date"]=>
string(10) "09/23/2013"
["text"]=>
string(15) "heya i'm a text"
}
}
You can test it here.
If the structure of the file is a coerent pattern of rows, with PHP you read each line and each 1st you have the number, each 2nd you have the date, each 3rd you have the text, each 4th you have empty, you reset the counter to 1 and go on like that, and put values in arrays, using even an external index, or the 1st line (number) as index.
try this:
EDIT: should now work for multi line text.
//convert the string into an array at newline.
$str_array = explode("\n", $str);
//remove empty lines.
foreach ($str_array as $key => $val) {
if ($val == "") {
unset($str_array[$key]);
}
}
$str_array = array_values($str_array);
$parsed_array = array();
$count = count($str_array);
$in_block = false;
$block_num = 0;
$date_pattern = "%[\d]{2}/[\d]{2}/[\d]{2,4}%";
for ($i = 0; $i < $count; $i++) {
//start the block at first numeric value.
if (isset($str_array[$i])
&& is_numeric(trim($str_array[$i]))) {
// make sure it's followed by a date value
if (isset($str_array[$i + 1])
&& preg_match($date_pattern, trim($str_array[$i + 1]))) {
//number, followed by date, block confirmed.
$in_block = true;
$block_num = $i;
$parsed_array[$str_array[$i]]["date"] = $str_array[$i + 1];
$parsed_array[$str_array[$i]]['text'] = "";
$i = $i + 2;
}
}
//once a block has been found, everything that
//is not "number followed by date" will be appended to the current block's text.
if ($in_block && isset($str_array[$i])) {
$parsed_array[$str_array[$block_num]]['text'].=$str_array[$i] . "\n";
}
}
var_dump($parsed_array);
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
HTTP_ACCEPT_LANGUAGE
i try to code a language option tool. therefor i use
$default_language = (strtolower($_SERVER["HTTP_ACCEPT_LANGUAGE"]));
if (eregi('af', $default_language)) {do something}
now i would like to order the string when i will echo:
$_SERVER["HTTP_ACCEPT_LANGUAGE"]
for example an user has specified a number of languages.
example for chrome with different languages:
nl,en-gb;q=0.8,en;q=0.6,fr;q=0.4,fr-ca;q=0.2
so how can i read out the string to bring it in a certain order where i can see that nl is the first language that is prefered.
the code should be something like:
if ('nl'== array[0]) {do something}
so if there is someone who could help me out i really would appreciate.
thanks alot.
From HTTP/1.1 Header Field Definitions:
Each language-range MAY be given an associated quality value which represents an estimate of the user's preference for the languages specified by that range. The quality value defaults to "q=1".
You have to loop over languages and select one with highest quality (preferrence); like this:
$preferred = "en"; // default
if(isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]))
{
$max = 0.0;
$langs = explode(",", $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
foreach($langs as $lang)
{
$lang = explode(';', $lang);
$q = (isset($lang[1])) ? ((float) $lang[1]) : 1.0;
if ($q > $max)
{
$max = $q;
$preferred = $lang[0];
}
}
$preferred = trim($preferred);
}
// now $preferred is user's preferred language
If Accept-Language header is not sent, all languages are equally acceptable.
How about explode()?
$array = explode(",",$_SERVER["HTTP_ACCEPT_LANGUAGE"]);
Given your example string, you should end up with the following values
$array[0] = "nl"
$array[1] = "en-gb;q=0.8"
$array[2] = "en;q=0.6"
etc.
If you prefer to assume that the string is not always ordered before it is sent by the browser then the following code will parse and sort it. Note that I've changed French's q to 0.9.
<?php
$lang = 'nl,en-gb;q=0.8,en;q=0.6,fr;q=0.9,fr-ca;q=0.2';
$langs = array();
foreach(explode(',', $lang) as $entry) {
$t1 = explode(';', $entry);
switch( count($t1) ) {
case 1:
$langs[] = array($t1[0], 1.0);
break;
case 2:
$t2 = explode('=', $t1[1]);
$langs[] = array($t1[0], floatval($t2[1]));
break;
default:
echo("what is this I don't even");
break;
}
}
function mysort($a, $b) {
if( $a[1] == $b[1] ) { return 0; }
elseif( $a[1] > $b[1] ) { return -1; }
else { return 1; }
}
usort($langs, 'mysort');
var_dump($langs);
Output:
array(5) {
[0]=>
array(2) {
[0]=>
string(2) "nl"
[1]=>
float(1)
}
[1]=>
array(2) {
[0]=>
string(2) "fr"
[1]=>
float(0.9)
}
[2]=>
array(2) {
[0]=>
string(5) "en-gb"
[1]=>
float(0.8)
}
[3]=>
array(2) {
[0]=>
string(2) "en"
[1]=>
float(0.6)
}
[4]=>
array(2) {
[0]=>
string(5) "fr-ca"
[1]=>
float(0.2)
}
}
try this :
<?php
print_r(Get_Client_Prefered_Language(true, $_SERVER['HTTP_ACCEPT_LANGUAGE']));
function Get_Client_Prefered_Language ($getSortedList = false, $acceptedLanguages = false)
{
if (empty($acceptedLanguages))
$acceptedLanguages = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
// regex borrowed from Gabriel Anderson on http://stackoverflow.com/questions/6038236/http-accept-language
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $acceptedLanguages, $lang_parse);
$langs = $lang_parse[1];
$ranks = $lang_parse[4];
// (recursive anonymous function)
$getRank = function ($j)use(&$getRank, &$ranks)
{
while (isset($ranks[$j]))
if (!$ranks[$j])
return $getRank($j + 1);
else
return $ranks[$j];
};
// (create an associative array 'language' => 'preference')
$lang2pref = array();
for($i=0; $i<count($langs); $i++)
$lang2pref[$langs[$i]] = (float) $getRank($i);
// (comparison function for uksort)
$cmpLangs = function ($a, $b) use ($lang2pref) {
if ($lang2pref[$a] > $lang2pref[$b])
return -1;
elseif ($lang2pref[$a] < $lang2pref[$b])
return 1;
elseif (strlen($a) > strlen($b))
return -1;
elseif (strlen($a) < strlen($b))
return 1;
else
return 0;
};
// sort the languages by prefered language and by the most specific region
uksort($lang2pref, $cmpLangs);
if ($getSortedList)
return $lang2pref;
// return the first value's key
reset($lang2pref);
return key($lang2pref);
}
The languages are ordered as the user prefers them. All you have to do is to split the string at the , symbol and from the parts, get rid off everything from the ; to the end (including the ;) and you have the languages in the user's prefered order.
PHP's explode function returns an array of strings split on some provided substring. It will return empty strings when there are leading, trailing, or consecutive delimiters, like this:
var_dump(explode('/', '1/2//3/'));
array(5) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[2]=>
string(0) ""
[3]=>
string(1) "3"
[4]=>
string(0) ""
}
Is there some different function or option or anything that would return everything except the empty strings?
var_dump(different_explode('/', '1/2//3/'));
array(3) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[2]=>
string(1) "3"
}
Try preg_split.
$exploded = preg_split('#/#', '1/2//3/', -1, PREG_SPLIT_NO_EMPTY);
array_filter will remove the blank fields, here is an example without the filter:
print_r(explode('/', '1/2//3/'))
prints:
Array
(
[0] => 1
[1] => 2
[2] =>
[3] => 3
[4] =>
)
With the filter:
php> print_r(array_filter(explode('/', '1/2//3/')))
Prints:
Array
(
[0] => 1
[1] => 2
[3] => 3
)
You'll get all values that resolve to "false" filtered out.
see http://uk.php.net/manual/en/function.array-filter.php
Just for variety:
array_diff(explode('/', '1/2//3/'), array(''))
This also works, but does mess up the array indexes unlike preg_split. Some people might like it better than having to declare a callback function to use array_filter.
function not_empty_string($s) {
return $s !== "";
}
array_filter(explode('/', '1/2//3/'), 'not_empty_string');
I have used this in TYPO3, look at the $onlyNonEmptyValues parameter:
function trimExplode($delim, $string, $onlyNonEmptyValues=0){
$temp = explode($delim,$string);
$newtemp=array();
while(list($key,$val)=each($temp)) {
if (!$onlyNonEmptyValues || strcmp("",trim($val))) {
$newtemp[]=trim($val);
}
}
reset($newtemp);
return $newtemp;
}
It doesn't mess up the indexes:
var_dump(trimExplode('/', '1/2//3/',1));
Result:
array(3) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[2]=>
string(1) "3"
}
Here is a solution that should output a newly indexed array.
$result = array_deflate( explode( $delim, $array) );
function array_deflate( $arr, $emptyval='' ){
$ret=[];
for($i=0,$L=count($arr); $i<$L; ++$i)
if($arr[$i] !== $emptyval) $ret[]=$arr[$i];
return $ret;
}
While fairly similar to some other suggestion, this implementation has the benefit of generic use. For arrays with non-string elements, provide a typed empty value as the second argument.
array_deflate( $objArray, new stdClass() );
array_deflate( $databaseArray, NULL );
array_deflate( $intArray, NULL );
array_deflate( $arrayArray, [] );
array_deflate( $assocArrayArray, [''=>NULL] );
array_deflate( $processedArray, new Exception('processing error') );
.
.
.
With an optional filter argument..
function array_deflate( $arr, $trigger='', $filter=NULL, $compare=NULL){
$ret=[];
if ($filter === NULL) $filter = function($el) { return $el; };
if ($compare === NULL) $compare = function($a,$b) { return $a===$b; };
for($i=0,$L=count($arr); $i<$L; ++$i)
if( !$compare(arr[$i],$trigger) ) $ret[]=$arr[$i];
else $filter($arr[$i]);
return $ret;
}
With usage..
function targetHandler($t){ /* .... */ }
array_deflate( $haystack, $needle, targetHandler );
Turning array_deflate into a way of processing choice elements and removing them from your array. Also nicer is to turn the if statement into a comparison function that is also passed as an argument in case you get fancy.
array_inflate being the reverse, would take an extra array as the first parameter which matches are pushed to while non-matches are filtered.
function array_inflate($dest,$src,$trigger='', $filter=NULL, $compare=NULL){
if ($filter === NULL) $filter = function($el) { return $el; };
if ($compare === NULL) $compare = function($a,$b) { return $a===$b; };
for($i=0,$L=count($src); $i<$L; ++$i)
if( $compare(src[$i],$trigger) ) $dest[]=$src[$i];
else $filter($src[$i]);
return $dest;
}
With usage..
$smartppl=[];
$smartppl=array_inflate( $smartppl,
$allppl,
(object)['intelligence'=>110],
cureStupid,
isSmart);
function isSmart($a,$threshold){
if( isset($a->intellgence) ) //has intelligence?
if( isset($threshold->intellgence) ) //has intelligence?
if( $a->intelligence >= $threshold->intelligence )
return true;
else return INVALID_THRESHOLD; //error
else return INVALID_TARGET; //error
return false;
}
function cureStupid($person){
$dangerous_chemical = selectNeurosteroid();
applyNeurosteroid($person, $dangerous_chemical);
if( isSmart($person,(object)['intelligence'=>110]) )
return $person;
else
lobotomize($person);
return $person;
}
Thus providing an ideal algorithm for the world's educational problems. Aaand I'll stop there before I tweak this into something else..
Write a wrapper function to strip them
function MyExplode($sep, $str)
{
$arr = explode($sep, $str);
foreach($arr as $item)
if(item != "")
$out[] = $item;
return $out;
}
Use this function to filter the output of the explode function
function filter_empty(&$arrayvar) {
$newarray = array();
foreach ($arrayvar as $k => $value)
if ($value !== "")
$newarray[$k] = $value;
$arrayvar = $newarray;
}
Regular expression solutions tend to be much slower than basic text replacement, so i'd replace double seperators with single seperators, trim the string of any whitespace and then use explode:
// assuming $source = '1/2//3/';
$source = str_replace('//', '/', $source);
$source = trim($source);
$parts = explode('/', $source);
No regex overhead - should be reasonably efficient, strlen just counts the bytes
Drop the array_values() if you don't care about indexes
Make it into function explode_interesting( $array, $fix_index = 0 ) if you want
$interesting = array_values(
array_filter(
explode('/', '/1//2//3///4/0/false' ),
function ($val) { return strlen($val); }
));
echo "<pre>", var_export( $interesting, true ), "</pre>";
enjoy, Jeff
PHP's split function is similar to the explode function, except that it allows you to enter a regex pattern as the delimiter. Something to the effect of:
$exploded_arr = split('/\/+/', '1/2//3/');
I usually wrap it in a call to array_filter, e.g.
var_dump(array_filter(explode('/', '1/2//3/'))
=>
array(3) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[3]=>
string(1) "3"
}
Be aware, of course, that array keys are maintained; if you don't want this behaviour, remember to add an outer wrapper call to array_values().