Two variables are not matching on PHP - php

So I have a string that for some reason, is returning as: 12×12. I did this in my code: utf8_decode($variant['size']) and received 12×12.
But this still isn't matching my string of 12x12
So I have 12×12 that is not showing as equal in php with: 12x12.
The X does look a little different but how do I fix this issue?

In 12×12 the × is the multiplication symbol, which obviously doesn't equate to x. Note that × doesn't reach the baseline in the text.
You should test for this multiplication symbol instead, if you can.

Related

How to get NumberFormatter::parse() to only parse actual numeric strings?

I’m trying to parse some strings in some messed-up CSV files (about 100,000 rows per file). Some columns have been squished together in some rows, and I’m trying to get them unsquished back into their proper columns. Part of the logic needed there is to find whether a substring in a given colum is numeric or not.
Non-numeric strings can be anything, including strings that happen to begin with a number; numeric strings are generally written the European way, with dots used for thousand separators and commas for decimals, so without going through a bunch of string replacements, is_numeric() won’t do the trick:
\var_dump(is_numeric('3.527,25')); // bool(FALSE)
I thought – naïvely, it transpires – that the right thing to do would be to use NumberFormatter::parse(), but it seems that function doesn’t actually check whether the string given as a whole is parseable as a numeric string at all – instead it just starts at the beginning and when it reaches a character not allowed in a numeric string, cuts off the rest.
Essentially, what I’m looking for is something that will yield this:
$formatter = new \NumberFormatter('de-DE', \NumberFormatter::DECIMAL);
\var_dump($formatter->parse('3.527,25')); // float(3527.25)
\var_dump($formatter->parse('3thisisnotanumber')); // bool(FALSE)
But all I can get is this:
$formatter = new \NumberFormatter('de-DE', \NumberFormatter::DECIMAL);
\var_dump($formatter->parse('3.527,25')); // float(3527.25)
\var_dump($formatter->parse('3thisisnotanumber')); // float(3)
I figured perhaps the problem was that the LENIENT_PARSE attribute was set to true, but setting it to false ($formatter->setAttribute(\NumberFormatter::LENIENT_PARSE, 0)) has no effect; non-numeric strings still get parsed just fine as long as they begin with a number.
Since there are so many rows and each row may have as many as ten columns that need to be validated, I’m looking at upwards of a million validations per file – for that reason, I would prefer avoiding a preg_match()-based solution, since a million regex match calls would be quite expensive.
Is there some way to tell the NumberFormatter class that you would like it to please not be lenient and only treat the string as parseable if the entire string is numeric?
You can strip all the separators and check if whatever remains is a numeric value.
function customIsNumeric(string $value): bool
{
return is_numeric(str_replace(['.', ','], '', $value));
}
Live test available here.
You can use is_numeric() to check that it is only numbers before parsing. But NumberFormatter does not do what you are looking for here.

How does IBM-850 encoding work with PHP function parameters?

In this code golf answer, aross gives a solution that presumably uses IBM-850 encoding as parameter values in PHP"
echo preg_filter("/^(.*?[aeiouy]+)/i","$1 $1 $0",$argn);
echo preg_filter(~ðíÎÐı└ñ×ÜûÉèåóÈÍðû,~█╬▀█╬▀█¤,$argn); # Encoded
How does this work? Why are the parameters not quoted? How come only the parameters are encoded and not the rest of the code?
It hasn't so much to do with IBM-850, that's just a codepage filling out the 8th bit beyond ASCII to give a representation to the bytes you'll end up with.
The key here is the bitwise not operator ~ which flips all the bits - 0 becomes 1, and 1 becomes 0. If you dump ~"/^(.*?[aeiouy]+)/i" to a file and open it up as 850 it'll look like:
ðíÎÐı└ñ×ÜûÉèåóÈÍðû
And likewise ~"$1 $1 $0" looks like:
█╬▀█╬▀█¤
So you see where this is headed.
In PHP an undefined constant is assumed to have a string value matching its name. For example:
var_dump(foo);
Outputs string(3) "foo" (as well as the notice "Use of undefined constant foo - assumed 'foo'", if notices are on.)
When either of the two gibberish strings above are put in a PHP script without quotes they're taken as undefined constants with their names assumed for their values as well.
Now prepend each with ~ to flip their bits back and you've got the original regex and replacement strings:
preg_filter("/^(.*?[aeiouy]+)/i","$1 $1 $0",$argn)
Only those parameters had their bits flipped because they're the only string literals, which is what this trick applies to. For each string it's shaving off a pair of quotes in exchange for taking on only a single tilde.
The bit flipping had to be done because either of the original strings on their own without quotes would've landed parse errors.
Clever way to net two bytes.

PHP Division by zero error where no math is present?

Warning: Division by zero in ..\session.php on line 2
After updating my PHP to the most current version my host allows (5.5.9) there was a small issue with the session path so I had to include a small snip-it of code before the session_start() to fix it. However this odd error is happening, apparently it thinks I am attempting to divide by zero? I would like to know how to fix that if it is possible, I assume it is just PHP being stupid however.
Thanks! :)
Below is the first few lines of code
<?php
session_save_path(“/tmp”);
session_start();
//error_reporting(0);
EDIT: Fixed the issue using the code below
session_save_path(realpath(dirname($_SERVER['DOCUMENT_ROOT']) . '/../session'));
ini_set('session.gc_probability', 1);
It's the difference in the quotes used. PHP thinks you're trying to divide a string by another string. Change that to regular double-quotes and the problem will be resolved.
Right now, this is what PHP sees:
“/tmp”
^--- first string
^--- division operator
^^^^--- second string
The string is cast to an int before the operation, and that effectively turns both sides to 0, hence causing the Division by zero warning. You'd have caught this if you had enabled error reporting.
You have smart quotes.
Your code is therefore being interpreted as:
Unquoted string literal “
Divide by...
Unquoted string literal tmp“
Division casts to numbers, both sides get cast to zero, result is 0/0.

How does .sprintf("%4.2f", value) function in PHP?

I'm working through some more PHP tutorials, specifically DevZone PHP 101, and am confused by:
echo .sprintf("%4.2f", (2 * $radius * pi()))
I found this
I think that means produce a floating-point field four positions wide with two decimal places, using the value of the first succeeding parameter.
That comes from the C/C++ line of programming languages. an sprintf() takes the first parameter as a format statement. Anything in it starting with a % is a field specifier; anything else is just printable text. So if you give a format statement with all text and no specifiers, it will print exactly the way it appears. With format specifiers, it needs data to work on.
But after trying some different values I'm still not getting it. It seems to me if the purpose of it in this case is just to limit the decimal to 2 places all I have to put is
.sprintf("%.2f", (2 * $radius * pi()))
What is the point of the 4 in the front of it? In the PHP Manual it leads me to believe it determines the total number of characters should be 4 but (a) thats not the case since the decimal point makes it 5 characters and (b) thats not the case because I tried changing it to a larger number like %8.2f and it didn't tack any zeros on to either end. Could someone please better explain this.
Thanks!
The first number %8.2f in the format specifier is for the filling length. Per default sprintf uses the space character.
You can see the effect with larger numbers:
printf("%20.2f", 1.23);
Will for example lead to:
1.23
There's 16 spaces before the number. The float takes up 4, and the fill length was set to 20 for instance. (Maybe you printed it out into the webpage, thus no padding spaces were visible..)
And there's an example further below on the sprintf manpage to use alternative padding characters:
printf("%'*20.2f", 1.23); // use the custom padding character '*'
Will result in:
****************1.23

php covert a Hexadecimal number 273ef9 into a path 27/3e/f9

As the title reads, what it is an effeicent way to covert a Hexadecimal number such as 273ef9 into a path such as 27/3e/f9 in PHP?
updated:::
actually, I want a unsual number convert to dexadecimal and furthr convert to a path....but may be we can skip the middle step.
How about combining a str_split with implode? Might not be super efficient but very readable:
implode('/',str_split("273ef9",2));
As a side note, this will of course work well with larger hex strings and can handle partial (3,5,7 in length) hex numbers (by just printing it as a single letter after the last slash).
Edit: With what you're asking now (decimal -> hex -> path), it would look like this:
$num = 2572025;
$hex = dechex($num);
implode('/',str_split($hex,2));
Of course, you can combine it for an even shorter but less readable representation:
implode('/',str_split(dechex($num),2));
The most efficient approach is to touch each character in the hex value exactly once, building up the string as you go. Because the string may have either an odd or even number of digits, you'll have to start with a check for this, outputting a single digit if it's an odd-length string. Then use a for loop to append groups of two digits, being careful with whether or not to add a slash. It will be a few lines of code.
Unless this code is being executed many millions of times, it probably isn't worth writing out this algorithm; Michael Petrov's is so readable and so nice. Go with this unless you have a real need to optimize.
By the way, to go from a decimal number to a hex string, just use dechex :)

Categories