How to lowercase string with special characters? - php

I have this array in PHP:
$weekdays = array(
"mandag" => 1,
"tirsdag" => 2,
"onsdag" => 3,
"torsdag" => 4,
"fredag" => 5,
"lørdag" => 6,
"søndag" => 7);
The function gets the day with random formats like all uppercase or one letter uppercase, I'm doing an strtolower from the variable and then comparing it with the array.
The problem comes here, when I do strtolower on the var with a special character like this one ø from søndag and lørdag, it doesn't recognize the string. How can I change the string to strtolower without modifying the special character?

Try mb_strtolower
$weekdays = array("Mandag" => 1, "Tirsdag" => 2, "Onsdag" => 3, "Torsdag" => 4, "Fredag" => 5, "Lørdag" => 6, "Søndag" => 7);
$weekdays = array_combine(
array_map('mb_strtolower', array_keys($weekdays)),
$weekdays
);
var_dump($weekdays);

...or if you want to check a specific item in the array you can simply run mb_strtolower($item, 'UTF-8') on it.
$happyDay = "SøndAg";
echo $happyDay . ' -> ' . mb_strtolower($happyDay, 'UTF-8');

Related

NumberFormatter parse Euro's with comma as decimal splitter

I've a big headache over this. Why isn't this code working?
<?php
setlocale(LC_MONETARY, 'nl');
$fmt = new NumberFormatter( 'nl', NumberFormatter::CURRENCY );
$num = "€2,50";
echo "We have ".$fmt->parseCurrency($num, $curr)." in $curr\n";
?>
I've tried this on both a Windows machine and at http://phpfiddle.org/. The expected outcome is We have 2.50 in EUR.
The dutch locale is as following:
>>> localeconv()
=> [
"decimal_point" => ",",
"thousands_sep" => ".",
"int_curr_symbol" => "EUR",
"currency_symbol" => b"€",
"mon_decimal_point" => ",",
"mon_thousands_sep" => ".",
"positive_sign" => "",
"negative_sign" => "-",
"int_frac_digits" => 2,
"frac_digits" => 2,
"p_cs_precedes" => 1,
"p_sep_by_space" => 1,
"n_cs_precedes" => 1,
"n_sep_by_space" => 1,
"p_sign_posn" => 4,
"n_sign_posn" => 4,
"grouping" => [
3,
],
"mon_grouping" => [
3,
],
]
The currency parser is super strange and expects a non breaking space UTF-8 sign between the currency symbol and the number.
This example works fine for me:
<?php
setlocale(LC_MONETARY, 'nl');
$fmt = new NumberFormatter( 'nl', NumberFormatter::CURRENCY );
$num = "€\xc2\xa02,50";
echo "We have ".$fmt->parseCurrency($num, $curr)." in $curr\n";
?>
\xc2\xa0 is the code for that breaking space.

Select multiple random column values from a two-dimensional array

I want to select 5 random ID's from my array of rows. Here is my array $test:
$test = [
['id' => 13, 'pets' => 8],
['id' => 15, 'pets' => 8],
['id' => 16, 'pets' => 10],
['id' => 17, 'pets' => 9],
['id' => 18, 'pets' => 10],
['id' => 19, 'pets' => 10],
['id' => 20, 'pets' => 0],
['id' => 21, 'pets' => 8],
['id' => 22, 'pets' => 9],
['id' => 23, 'pets' => 4],
['id' => 24, 'pets' => 0],
['id' => 40, 'pets' => 8],
['id' => 43, 'pets' => 2],
];
How can I select 5 random ID's from the array and put them into a string like this:
$ids = '13,17,18,21,43';
I've tried to use array_rand(), but it does not seem to work for my type of array. I'm not sure if there are any other built in PHP functions that can do this type of job or if I have to create my own function. It would be nice to have my own function like this to plug in the number of required values.
You can use array_column to only get the ID's and shuffle them.
Then use array_slice to get five items and implode.
$id = array_column($arr, "id");
Shuffle($id);
Echo implode(",", array_slice($id, 0, 5));
First extract the id column indexing also by the id, then pick 5 random ones, and finally implode into a comma separated list. Since keys must be unique, this has the added benefit of not returning duplicate ids if there happen to be duplicates in the array:
$ids = implode(',', array_rand(array_column($test, 'id', 'id'), 5));
For a function:
function array_rand_multi($array, $key, $num) {
return implode(',', array_rand(array_column($array, $key, $key), $num));
}
If you want random, unique ids in a random order, I recommend shuffling the array, then isolating upto 5 subarrays, then extracting the id values, then joining with commas. This way array_column() doesn't need to iterate the full array.
Code: (Demo)
shuffle($test);
echo implode(
',',
array_column(
array_slice($test, -5),
'id'
)
);
If you want random, unique ids and don't mind that they will be in the same order as your input rows, then array_rand() can be used.
#AbraCadaver's approach works by applying temporary keys to the input array, picking five random keys, then joining with commas. Because the values inside the rows are never used, null can also be used as array_column()'s second parameter. These approaches should not be used if duplicate ids need to be honored. In other words, because id values are being applied to the first level keys, php will automatically destroy any rows with duplicated ids -- because a single level of an array cannot contain duplicate keys.
One way to avoid potentially destroying data is to call array_rand() on the original indexes of the input array, then filter those unique indexes by 5 randomly selected indexes. (Demo)
echo implode(
',',
array_column(
array_intersect_key(
$test,
array_flip(array_rand($test, 5))
),
'id'
)
);
Finally, if you want 5 randomly selected, randomly ordered ids which may be selected more than once, then just make 5 iterated calls of array_rand(). (Demo)
for ($x = 0, $delim = ''; $x < 5; ++$x, $delim = ',') {
echo $delim . $test[array_rand($test)]['id'];
}
Or (Demo)
echo implode(
',',
array_map(
fn() => $test[array_rand($test)]['id'],
range(1, 5)
)
);
You can proceed like this (short example) :
<?php
$items = array(
array("id" => 43, "pets" =>2),
array("id" => 40, "pets" =>8),
array("id" => 24, "pets" =>0),
array("id" => 23, "pets" =>4),
);
$ids = $items[array_rand($items)]["id"].",".$items[array_rand($items)]["id"].",".$items[array_rand($items)]["id"];
echo $ids;
// Output Example : 24, 40, 23
?>
It will choose a random key from the main array ($items), example : 3, and output the "id" :
$items[3]["id"]
for this example.
Here is a demo : http://sandbox.onlinephpfunctions.com/code/32787091e341cdf8e172d96b065b14b3ca834846

how can i replace some things in my array?

I need to format a date in my array - but the date in the array isn't saved as a datetime in a database or something like this.. I've got the dates from my server with cut them out.
So I need to work with preg_replace or with str_replace
What I've tried so far using str_replace:
$reverse_date = str_replace( '[', '' ,$reverse_date);
$reverse_date = str_replace( ']', '' ,$reverse_date);
$reverse_date = str_replace( '/', '.' ,$reverse_date);
but I don't want to use three lines for this.
If I print_r this, I will get : 12.Oct.2015:01:10:43 +0200
before it was looking like this : [12/Oct/2015:00:37:29 +0200]
so this is okay ! But I still don't want to use three lines for this, but I don't understand the preg_replace syntax
I want the following output :
12.Oct.2015(space)01:10:43 +0200
As you have said you were getting a date from an array within the following format
[12/Oct/2015:00:37:29 +0200]
So instead of using str_replace or preg_replace you can simply use DateTime::createFromFormat function of PHP like as
$date = DateTime::createFromFormat("[d/M/Y:H:i:s P]","[12/Oct/2015:00:37:29 +0200]");
echo $date->format('d.M.Y H:i:s P');//12.Oct.2015 00:37:29 +02:00
Demo
Use date_parse to disassemble the date and combine the parts to form your needed result:
[40] boris> $date_array = date_parse(" [12/Oct/2015:00:37:29 +0200] ");
// array(
// 'year' => 2015,
// 'month' => 10,
// 'day' => 12,
// 'hour' => 0,
// 'minute' => 37,
// 'second' => 29,
// 'fraction' => 0,
// 'warning_count' => 0,
// 'warnings' => array(
//
// ),
// 'error_count' => 2,
// 'errors' => array(
// 0 => 'Unexpected character',
// 27 => 'Unexpected character'
// ),
// 'is_localtime' => true,
// 'zone_type' => 1,
// 'zone' => -120,
// 'is_dst' => false
// )
You don't have the month as abbreviated string, but that is trivial to add via an associative array (array(1 => 'Jan', ..., 12 => 'Dec')), and you are on the safe side concerning the date-parsing stuff and future changes in your needs.
Ok I found out how to do it with preg_replace in one line, however I like the Uchiha answer with the date format more - even that he is not using the regex, this is probably the best way to go.
echo preg_replace(['~(?<=\d{4}:\d{2}):~', '~[\[]~', '~[\]]~', '~[\/]~g'],[' ', '', '', '.'],'[12/Oct/2015:00:37:29 +0200]');
12.Oct.2015:00 37:29 +0200

Convert a PHP date format to a jQueryUI Datepicker date format

[EDIT] : I guess people had problem to understand exactly what I mean, so I completely rewrote my explanations.
I work on a project where users can define a date format used in the whole site. It uses PHP date format standard. For example : "year-month-day" is set by "Y-m-d".
PHP standard uses single-character symbols like Y, m, d, F, j to describe the date format. As seen in the documentation : http://www.php.net/manual/en/function.date.php
Sometimes users can select a date thanks to a jQueryUI Datepicker. This component describes its date format with code-words like yy, y, mm, dd, D, ...
http://api.jqueryui.com/datepicker/#utility-formatDate
I would like to display the dates in the same format for both PHP and the Datepicker.
I mean that PHP should output the date as in the format set by user, AND the Datepicker should show the selected date in the same format.
Given that:
The date format is necessarily described "PHP style"
I can't know a priori which format was set by users
/!\ This not a problem of how to read/parse/display a date from a known format.
Unfortunately, Javascript date format description is not the same as in PHP.
For instance, these 2 date formats are equivalent but described differently in PHP and Javascript:
PHP : Y-m-d (set by users)
Javascript : yy-mm-dd
As you can see, I cannot just configure the datepicker with the PHP date format, because it will be misunderstood, or not recognized at all.
Someone (in answers below) adviced to create my own "date format standard converter", matching each PHP symbol with its equivalent in JS date format description. Just like:
Y => yy
m => mm
d => dd
y => y
z => o
...
And then replace each PHP symbol with the JS one. And so "d/m/Y" will be translated into "dd/mm/yy", magically.
But maybe somebody knows another proper way to make jQueryUI Datepicker understand PHP date format standard?
EDIT: I wrote a tutorial that explains both the problem and the solution. For further reading : http://tristan-jahier.fr/blog/2013/08/convertir-un-format-de-date-php-en-format-de-date-jqueryui-datepicker
I chose the brutal method : converting symbol-by-symbol the date format.
I made a 'not-so-dummy' code snippet.
/*
 * Matches each symbol of PHP date format standard
 * with jQuery equivalent codeword
* #author Tristan Jahier
 */
function dateformat_PHP_to_jQueryUI($php_format)
{
    $SYMBOLS_MATCHING = array(
        // Day
        'd' => 'dd',
        'D' => 'D',
        'j' => 'd',
        'l' => 'DD',
        'N' => '',
        'S' => '',
        'w' => '',
        'z' => 'o',
        // Week
        'W' => '',
        // Month
        'F' => 'MM',
        'm' => 'mm',
        'M' => 'M',
        'n' => 'm',
        't' => '',
        // Year
        'L' => '',
        'o' => '',
        'Y' => 'yy',
        'y' => 'y',
        // Time
        'a' => '',
        'A' => '',
        'B' => '',
        'g' => '',
        'G' => '',
        'h' => '',
        'H' => '',
        'i' => '',
        's' => '',
        'u' => ''
    );
    $jqueryui_format = "";
    $escaping = false;
    for($i = 0; $i < strlen($php_format); $i++)
    {
        $char = $php_format[$i];
        if($char === '\\') // PHP date format escaping character
        {
            $i++;
            if($escaping) $jqueryui_format .= $php_format[$i];
            else $jqueryui_format .= '\'' . $php_format[$i];
            $escaping = true;
        }
        else
        {
            if($escaping) { $jqueryui_format .= "'"; $escaping = false; }
            if(isset($SYMBOLS_MATCHING[$char]))
                $jqueryui_format .= $SYMBOLS_MATCHING[$char];
            else
                $jqueryui_format .= $char;
        }
    }
    return $jqueryui_format;
}
This function handles all the common codewords between PHP and Datepicker date format standards.
Plus, I added support for character escaping :
d m \o\f Y becomes dd mm 'of' yy
You may still have problems with symbols like 'W', 'L' that have no equivalent handled by Datepicker.
You cannot use the same format with datepicker that you're using with PHP.
Since PHP's date format only uses single letter codes, you're better off just taking the PHP date format and replacing each code to the corresponding value in the jQuery datepicker format, e.g.:
$PHPFormatOptions = array('y', 'Y', 'm', 'd');
$JSFormatOptions = array('yy', 'yyyy', 'mm', 'dd'); // and so on
$JSFormat = str_replace($PHPFormatOptions, $JSFormatOptions, $PHPFormat);
Not sure I'm quite with you, but this really shouldn't be an issue. You could either parse the front-end input: using DateTime::createFromFormat cf. php documentation for this, or use JSON.
Since JSON has an accepted standard way of formatting date strings, you can pass a JSON-stringified version of the input date to PHP, and json_decode it server-side. Both of these solutions are open to you, though I believe the first one to be easier to implement in your case.
If you want to be able to choose the format on both sides, the DateTime object is definitely what you need:
$date = new DateTime();
echo $date->format('Y-m-d').' <==> '.$date->format('y-M-j');
$postDate = $date->createFromFormat('y-m-d',$_POST['submitDate']);
echo $postDate->format('Y-m-d');
The format is explained on the page I've linked to.
Here is the solution:
function datepicker_format($format) {
static $assoc = array(
'Y' => 'yyyy',
'y' => 'yy',
'F' => 'MM',
'm' => 'mm',
'l' => 'DD',
'd' => 'dd',
'D' => 'D',
'j' => 'd',
'M' => 'M',
'n' => 'm',
'z' => 'o',
'N' => '',
'S' => '',
'w' => '',
'W' => '',
't' => '',
'L' => '',
'o' => '',
'a' => '',
'A' => '',
'B' => '',
'g' => '',
'G' => '',
'h' => '',
'H' => '',
'i' => '',
's' => '',
'u' => ''
);
$keys = array_keys($assoc);
$indeces = array_map(function($index) {
return '{{' . $index . '}}';
}, array_keys($keys));
$format = str_replace($keys, $indeces, $format);
return str_replace($indeces, $assoc, $format);
}
The magic double str_replace call caused by duplicating in needles and its replacement values, so that's why the string
m/d/Y
becomes
{{3}}/{{5}}/{{1}}
and after that this nests replacing with actual replacement values:
mm/dd/yy
Ok so the best solution for you would be to store everything in your website using time();
As far as I know datepicker can be set to work with dates for PHP timestamp
dateFormat : 'yy-mm-dd',
Edit :
Why would you store a date like : Y-m-d ?
It should be stored as timestamp or int

get integer / float from string in PHP

I ran into an issue with a data feed I need to import where for some reason the feed producer has decided to provide data that should clearly be either INT or FLOAT as strings-- like this:
$CASES_SOLD = "THREE";
$CASES_STOCKED = "FOUR";
Is there a way in PHP to interpret the text string as the actual integer?
EDIT: I should be more clear-- I need to have the $cases_sold etc. as an integer-- so I can then manipulate them as digits, store in database as INT, etc.
Use an associative array, for example:
$map = array("ONE" => 1, "TWO" => 2, "THREE" => 3, "FOUR" => 4);
$CASES_SOLD = $map["THREE"]; // 3
If you are only interested by "converting" one to nine, you may use the following code:
$convert = array('one' => 1,
'two' => 2,
'three' => 3,
'four' => 4,
'five' => 5,
'six' => 6,
'seven' => 7,
'eight' => 8,
'nine' => 9
);
echo $convert[strtolower($CASES_SOLD)]; // will display 3
If you only need the base 10 numerals, just make a map
$numberMap = array(
'ONE' => 1
, 'TWO' => 2
, 'THREE' => 3
// etc..
);
$number = $numberMap[$CASES_SOLD];
// $number == 3'
If you need something more complex, like interpreting Four Thousand Two Hundred Fifty Eight into 4258 then you'll need to roll up your sleeves and look at this related question.
Impress your fellow programmers by handling this in a totally obtuse way:
<?php
$text = 'four';
if(ereg("[[.$text.]]", "0123456789", $m)) {
$value = (int) $m[0];
echo $value;
}
?>
You need a list of numbers in english and then replace to string, but, you should play with 'thousand' and 'million' clause where must check if after string 'thousend-three' and remove integer from string.
You should play with this function and try change if-else and add some functionality for good conversion:
I'm writing now a simple code for basic, but you know others what should change, play!
Look at million, thousand and string AND, it should be change if no in string like '1345'. Than replace with str_replace each of them separaterly and join them to integer.
function conv($string)
{
$conv = array(
'ONE' => 1,
'TWO' => 2,
'THREE' => 3,
'FOUR' => 4,
'FIVE' => 5,
'SIX' => 6,
'SEVEN' => 7,
'EIGHT' => 8,
'NINE' => 9,
'TEN' => 10,
'ELEVEN' => 11,
'TWELVE' => 12,
'THIRTEEN' => 13,
'FOURTEEN' => 14,
'FIFTEEN' => 15,
'SIXTEEN' => 16,
'SEVENTEEN' => 17,
'EIGHTEEN' => 18,
'NINETEEN' => 19,
'TWENTY' => 20,
'THIRTY' => 30,
'FORTY' => 40,
'FIFTY' => 50,
'SIXTY' => 60,
'SEVENTY' => 70,
'EIGTHY' => 80,
'NINETY' => 90,
'HUNDRED' => 00,
'AND' => '',
'THOUSAND' => 000
'MILLION' => 000000,
);
if (stristr('-', $string))
{
$val = explode('-', $string);
#hardcode some programming logic for checkers if thousands, should if trim zero or not, check if another values
foreach ($conv as $conv_k => $conv_v)
{
$string[] = str_replace($conv_k, $conv_v, $string);
}
return join($string);
}
else
{
foreach ($conv as $conv_k => $conv_v)
{
$string[] = str_replace($conv_k, $conv_v, $string);
}
return join($string);
}
}
Basically what you want is to write a parser for the formal grammar that represents written numbers (up to some finite upper bound). Depending on how high you need to go, the parser could be as trivial as
$numbers = ('zero', 'one', 'two', 'three');
$input = 'TWO';
$result = array_search(strtolower($input), $numbers);
...or as involved as a full-blown parser generated by a tool as ANTLR. Since you probably only need to process relatively small numbers, the most practical solution might be to manually hand-code a small parser. You can take a look here for the ready-made grammar and implement it in PHP.
This is similar to Converting words to numbers in PHP
PHP doesn't have built in conversion functionality. You'd have to build your own logic based on switch statements or otherwise.
Or use an existing library like:
http://www.phpclasses.org/package/7082-PHP-Convert-a-string-of-English-words-to-numbers.html

Categories