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

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.

Related

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

Hypothetical concatenation predicament

So I am working on a simple micro language/alternative syntax for PHP.
Its syntax takes a lot from JavaScript and CoffeeScript including a few of my own concepts. I have hand written the parser (no parser generator used) in PHP to convert the code into PHP then execute it. It is more of a proof of concept/learning tool rather than anything else but I'd be lying if I said I didn't want to see it used on an actual project one day.
Anyway here is a little problem I have come across that I thought I would impose on you great intellects:
As you know in PHP the period ( . ) is used for string concatenation. However in JavaScript it is used for method chaining.
Now one thing that annoys me in PHP is having to do use that bloody arrow (->) for my method chains, so I went the JavaScript way and implemented the period (.) for use with objects.
(I think you can see the problem already)
Because I'm currently only writing a 'dumb' parser that merely does a huge search and replace, there is no way to distinguish whether a period (.) is being used for concatenation or for method chaining.
"So if you are trying to be like JavaScript, just use the addition (+) operator Franky!", I hear you scream. Well I would but because the addition (+) operator is used for math in PHP I would merely be putting myself in the same situation.
Unless I can make my parser smart enough (with a crap load of work) to know that when the addition (+) operator is working with integers then don't convert it into a period (.) for concatenation I am pretty much screwed.
But here is the cool thing. Because this is pretty much a new language. I don't have to use the period or addition operator for concatenation.
So my question is: If I was to decide to introduce a new method of string concatenation, what character would make the most sense?
Does it have to be one character? .. could work!
Any myriad of combinations, like ~~ or >: even!
If you don't want to use + or ., then I would recommend ^ because that's used in some other languages for string concatenation and I don't believe that it's used for anything in PHP.
Edit: It's been pointed out that it's used for XOR. One option would be to use ^ anyway since bitwise XOR is not commonly used and then to map something else like ^^ to XOR. Another option would be to use .. for concatenation. The problem is that the single characters are mostly taken.
Another option would be to use +, but map it to a function which concatenates when one argument is a string and adds otherwise. In order to not break things which rely on strings which are numbers being treated as their values, we should probably treat numeric strings as numbers for these purposes. Here's the function that I would use.
function smart_add($arg1,$arg2) {
if ($arg1.is_numeric() && $arg2.is_numeric()) {
return $arg1 + $arg2;
} else {
return $arg1 . $arg2;
}
}
Then a + b + c + d just gets turned into smart_add(smart_add(smart_add(a,b),c),d)
This may not be perfect in all cases, but it should work pretty well most of the time and has clear rules for use.
So my question is: If I was to decide to introduce a new method of
string concatenation, what character would make the most sense?
As you're well aware of, you'll need to chose a character that is not being used as one of PHP's operators. Since string concatenation is a common technique, I would try to avoid using characters that you need to press SHIFT to type, as those characters will be a hindrance.
Instead of trying to assign one character for string concatenation (as most are already in use), perhaps you should define your own syntax for string concatenation (or any other operation you need to overwrite with a different operator), as a shorthand operator (sort of). Something like:
[$string, $string]
Should be easy to pick up by a parser and form the resulting concatenated string.
Edit: I should also note that whether you're using literal strings or variables, there's no way (as far as I know) to confuse this syntax with any other PHP functionality, since the comma in the middle is invalid for array manipulations. So, all of the following would still be recognized as string concatenation and not something else in PHP.
["stack", "overflow"]
["stack", $overflow]
[$stack, $overflow]
Edit: Since this conflicts to JSON notation, the following alternative variations exist:
Changing the delimiter
Omitting the delimiter
Example:
[$stack $overflow $string $concatenation] // Use nothing (but really need space)

Which is better to use: $arrayName['literal'] or $arrayName[literal]?

Both are working fine. I'm just curious how php parse the two. Do they have difference on speed, efficiency, etc. Why does php allow us to use both?
Difference is that the first ('literal') is a string key and that the second one is undefined constant. PHP allows you to use both because devs tried to fix bad code of people who weren't paying attention while reading the docs. There's a difference in speed since the second one will raise a warning - undefined constant. Basically, don't use the second one.
if you are using just literal php recognizes this as a constant. So it try to find that constant, and if it fails - it just assumes that your desire was using string literal 'literal'. But, to indicate that it doesn't found the constant it raises Notice level error.
So, using just literal have tweo drawbacks:
If you have constant literal defined - you'll get it's value (and this is a correct usage), not string 'literal'
You'll receive a Notice if you don't have such constant.
So, don't use just literal unless you have a constant with that name defined.
$arrayName[literal] is bad because if you have constant named literal, you'll get unexpected results. When it's no constant named literal, php transforms literal to string 'literal'
http://php.net/manual/en/language.types.array.php
Array do's and don'ts
*Why is $foo[bar] wrong?*
Always use quotes around a string literal array index. For example,
$foo['bar'] is correct, while $foo[bar] is not. But why? It is common
to encounter this kind of syntax in old scripts:
<?php
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
?>
This is wrong, but it works. The reason is that this code has an
undefined constant (bar) rather than a string ('bar' - notice the quotes). PHP may in future define constants which, unfortunately for
such code, have the same name. It works because PHP automatically
converts a bare string (an unquoted string which does not correspond
to any known symbol) into a string which contains the bare string. For
instance, if there is no defined constant named bar, then PHP will
substitute in the string 'bar' and use that.

printf function in PHP

I'm from a C background and understand basics of printf function.
I came across the follwing code
<?php
printf('%4$d %2$s code for %3$3.2f %1$s', "hours", "coders", 9, 99);
?>
which prints:
99 coders code for 9.00 hours
Can anyone help me in understanding the call to the printf function.
<n>$ means "use the nth argument, instead of whatever position you are in formatting specs".
The first argument of the printf function is a String that gets altered using the other arguments:
%4d - takes the 4th item after the comma and treats it as a decimal number
%2$s - takes the 2nd item after the comma and treats it as a String
%3$3.2f - takes the 3rd itam after the comma and treats it as a floating number with two decimal places
%1$s - takes the first item after the comma and treats it as a String
Ignacio's answer is correct.
One very useful application of this feature if you're using gettext for I18N. The order of substitution might change between one language and another. (though if you're wrapping stuff in calls to gettext, you'd be using sprintf).
I'm drawing a blank on a real-world example, guess I don't speak enough natural languages.
I think some of the confusion might have been an error in the code:
%3$3.2f should read %3$.2f instead (but it works either way).
Not sure what the difficulty is, because it's fairly well documented in the manual:
The first argument is the format mask, subsequent arguments are values to insert into the format mask. Rules for masking are the same as in C. And like in C, output is sent directly to stdout

How to use $_SERVER['REQUEST_URI']

Is there any difference between typing:
<?php echo $_SERVER[REQUEST_URI] ?>
or
<?php echo $_SERVER['REQUEST_URI'] ?>
or
<?php echo $_SERVER["REQUEST_URI"] ?>
?
They all work... I use the first one.
Maybe one is faster than the other?
Without quotes PHP interprets the REQUEST_URI as a constant but corrects your typo error if there is no such constant and interprets it as string.
When error_reporting includes E_NOTICE, you would probably get an error such as:
Notice: Use of undefined constant REQUEST_URI - assumed 'REQUEST_URI' in <file path> on line <line number>
But if there is a constant with this name, PHP will use the constant’s value instead. (See also Array do's and don'ts)
So always use quotes when you mean a string. Otherwise it can have unwanted side effects.
And for the difference of single and double quoted strings, see the PHP manual about strings.
The first one is wrong - you're actually looking for a constant REQUEST_URI that doesn't exist. This will generate a notice-level warning.
There's no difference between the other two.
There is a difference between single and double quotes in PHP string handling. A string enclosed in double quotes will be evaluated for embedded variables and escape characters (e.g. \n); a string enclosed in single quotes won't (or not as much).
So, for example,
$hello = "world";
echo "Hello $hello!\n";
echo 'Hello $hello!\n';
echo 'Done';
will output
Hello world!Hello $hello!\nDone
In situations where you have no escape characters or embedded variables, it is slightly more efficient to use single quotes as it requires less processing of the string by the runtime. However, many people (me included) prefer to use double quotes for all strings to save confusion.
As a caveat to Gumbo's answer the third representation - double quotes - actually makes PHP look for variables inside that string. Thus that method might be a little slower (although in a string of 11 characters it'll be negligible - it's better practice not to make PHP do that however).
When PHP comes across plain strings being used as array keys it checks if there is a constant with that name and if there isn't it defaults it back to an array key. Therefore, not using quote marks causes a slight performance hit and there is a possibility that the result will not be what you expect.
$_SERVER[REQUEST_URI]
is syntatically incorrect and AFAIK will not run on a default installation of PHP5. The array index is a string so it needs to be passed on strings. I know PHP4 converted undefined constants to strings inside the square brackets but it's still not good practice.
EDIT: Well unless you define a constant called REQUEST_URI, which you haven't in your example script.
$_SERVER['REQUEST_URI']
is the standard method and what you should be using.
$_SERVER["REQUEST_URI"]
also works and while not wrong is slightly more work for the PHP interpreter so unless you need to parse it for variables should not be used. (and if you need to do so, you need to rethink that part of your program.

Categories