What makes ME sad is no keyword arguments. Helper/wrapper functions either get an annoying and difficult-to-grok-at-glance associative-array for it's params (bad), or a huge list of rarely-used parameters (worse), or a huge set of wrapper functions to set their own paramters (even worse), or outright duplicated functions for similar-but-not-quite tasks (worst).
This happens to me while producing something like a jqGrid, or other javascript/html hybrid stuff that need a few extra options sometimes.
Django/Python? No problem! Just use the keywords you need.
(More Info: The difference between a single associative param standing in for keywords arguments, or a huge list of regular arguments is a choice in complexity/readability IN the function vs. calling it.
For the single dictionary approach, you lost the built-in parameter defaults nicety, which means you need to handle the case of a missing parameter manually. This kind of sucks, especially if you hate seeing PHP Notices during development (which kill JSON/XML output anyway). This makes your function often twice as big (or more) than it needs to be.
For the other approach, you wind up with calling
foo("","","","real value", true, true, 2, false, false, "option I want");*
which just about invites all sorts of hard-to-find bugs, and you have to look at the function definition every time you want to change an option. Also, it's flat-out rude if you aren't the one calling the function.)
If you want to `sanitize' which arguments can be passed that way, use extract(array_intersect_key($allowed, $kwargs)); ((EDIT: or use EXTR_IF_EXISTS)).
Nb., extract() works on any associative array, you don't have to use compact().
You can use the @ symbol to suppress errors when you're aware that the variable may be empty and you've considered the possible effects. When I used to write PHP, I'd often write something like
do_something(@$_GET['foobar']);
There are ways to suppress PHP notices without just turning off the E_NOTICE output.
There's a lot of valid points there, but "#33
Cannot override private methods with a subclass" is the right behavior. That's exactly what private is for, and it's important to know that such names are non-colliding and you can rely on their implementation.
Use protected for overridable methods. You shouldn't mock or directly test private methods in unit tests — they're not part of the interface!
public/protected/private is a dumb idea in dynamic languages. If you don't want someone calling your method, prefix it with an underscore and say "the results are undefined if you call methods that start with an underscore". Done. Easier to maintain, easier to test, less code to type in.
Come to think of it... public/protected/private is a dumb idea in C++ and Java, too.
Before everyone goes all "why don't you switch to language X or platform Y or lisp variant Z" I just want to say good job on this.
These all seem to be sane critiques of PHP without being all doomsday world-ending inflamatory. Kudos.
Also, I think that this is another example of how hard it is to build up a large and widely-used language/framework without having lots of warts. Especially since PHP wasn't originally designed with the intention of powering everything from a simple blog/cms to facebook.
I've definitely run into #1 on the list. "Paamayim Nekudotayim" is a transliterated version of פעמיים נקודתיים, which means "double colon" in Hebrew. Zeev and Andi are Israeli, which kind of explains it, but the error message is still pretty useless.
Of all these complaints, I’m most forgiving of the name of T_PAAMAYIM_NEKUDOTAYIM. You only need to look it up once; the cost is a few seconds of Googling and the payoff is you learn a fun random fact. It gives the language a bit of color.
not at all. A google search for "Paamayim Nekudotayim" gives you thousands of pages relating to exactly the error you're experiencing. It's WAY more useful than "Illegal operation" or "Syntax error".
Its only a "bug" because there's an unspoken rule that all programming languages should be written in English, and English doesn't have a proper word for this symbol.
Pretend that English had no representation of an ellipsis, but Hebrew did. Should the language author say "Expected: dot-dot-dot" in the error message to appease native English speakers, or should (s)he use the unambiguous form?
The way I've explained this (braindead) behaviour to people is that == is the 'equivalence' operator, and === is the 'equality' operator.
This sort of 'well, close enough' behaviour has bitten me in the past as well. While writing a JSON bridge between an older PHP backend system and a newer Rails frontend, we kept getting exceptions on the Rails end.
It turns out that the JSON library uses isnumeric() to determine if a value is a number or not - which makes sense, in some respects. The problem is that we had a parameter (the external vendor's product SKU) which was a string that, in some cases, consisted entirely of digits. On those few occasions, the JSON library would say 'Oh, this is a number' and encode it as such in the JSON.
When Rails tried to unpack it, we got an exception because our Rails model was validating the data on the remote end and choked on getting an integer instead of a string.
We ended up having to actually modify the JSON library we were using (everything else we tried either didn't work or had the same bug) to modify the check. Completely ridiculous.
I want to make sure that object A and object B are instances of the same class. Also, I want to make sure that they are equal i.e. that every attribute is equal. Also, since I'm now used to always using === instead of == for such comparisons, I use === to make the comparison. I would think that == would perform an == comparison on every attribute, whereas === would perform an === comparison on every attribute.
Nope! Using === actually verifies that the A and B are in fact references to the same object in memory, just like the "is" operator in Python. Got me again, PHP! How do I do my === comparison? Manually, that's how!
As usual, when one of these lists comes out about PHP there are some real issues, some non-issues, some have been fixed, and a few things that are just different. I'm surprised these sorts of posts keep getting voted up here; haven't we seen it all before?
I do a lot of PHP development but not exclusively and rarely does these sorts of deficiencies in PHP ultimately matter.
I had it a little wrong in the initial report, but it was cleared up in the comments. The reluctance to fix stuff like this because "people might use this for some weird reason" is one of the reasons I'm glad I don't write much PHP anymore.
I hate PHP, but this article isn't very good. It's strange that there is an "implications for the internals" reason. Guess what, you can just read the internals. It's open source.
The parser emits weird error messages because it is a very simple yacc grammar. (And because they turn off yacc's "produce better error messages" mode.) If you want good error messages, it's going to cost you -- just read perl's toke.c if you don't believe me. Good error messages cost a lot.
While it doesn't detract from the point of your post, the behavior of private is correct and intended. If you wish to override an internal method of a class in PHP, like Java, you must declare it protected, not private. This is the difference between private (completely internal, not inherited) and protected (internal, but inherited by subclasses).
I'd love to see similar lists for other languages. I've been coding in MATLAB as of late, for instance, and rediscovered my hatred for the fact that you can't index the output of a function without assigning to a temporary variable. For instance, `foo(args)(:)` causes an error. You have to use `X = foo(args); X(:)` instead. That makes me just as sad as some of these PHP sadnesses.
MATLAB does get one thing right: Function arguments are always passed by value. This "referential transparency" really makes it easier to reason about functions and test them.
It's the one thing I hate about SciPy.
Passing by reference for performance reasons should be automatically handled by the compiler. I.e., A=sort(A) should be handled in-place without requiring a new function sort!(A).
Yes. Though Matlab has gotten massively better in recent years. It's just that the defaults, for backwards compatibility are still The Wrong Thing (TM). Look at function handles, and cells for string handling.
That's called array dereferencing. It doesn't work in php either, you need to assign to a temporary variable. I've been following a patch in the works (at https://wiki.php.net/rfc/functionarraydereferencing ) but there doesn't seem to be much progress on it.
I clicked on a random item - the complaint that explode() doesn't take the empty string and return an array of each letter. But of course you can just use the str_split() function to do that (which is way more logical than passing an empty string).
So how do I contact the author and reduce his sadness level?
Or is this one of those websites that don't want to remove items, even if they are wrong?
you could say that all other web platforms are blub because they don't see the value that PHP brings to the table.
a total idiot can install PHP and get a system that will meet the performance and reliability needs of 99.5 of web sites out there.
tomcat, mod_perl, the ten different ways people host Ruby sites and all that make a lot more trouble for you. I've run PHP-based web servers for hundreds of sites that have served billions and billions of hits over the years and never once had to restart Apache because an application server got lodged. read that again because if you skip it, you're sysadminning blub.
every other system requires that you make choices, and the truth about choices is that faced with a binary choice there are two common outcomes: (i) a person freezes up like a deer in the headlights or (ii) a person makes a random choice that they're 50% likely to get right. (i)'s probably the better option.
i can complain about things wrong with PHP forever and i've got plenty of reasons to get off the PHP train. however, if you want to kill PHP, it's not enough to attack what's wrong with PHP, you've got attack what's right with PHP... You've got to make a better PHP than PHP.
#40 is a major WTF. They are outright removing the ability to create a length 1 buffer, so that someone who wants to create a 4096 unit buffer can save 3 keystrokes?
(Also, what if the length argument is dynamically generated, say from the size of a file?)
Programming languages are tools. Some tools are better than others, some are better for certain situations. For all non-contractors, no one is forcing you to write in one language over another (or stay employed at a php shop).
It seems like the only point of having threads like this is for the leet programmers to look down on php. What's the point? This isn't constructive, its condescending and back-patting.
(the reason this makes me mad is that the sadness list is just a bunch of minor gripes. Every language has minor problems. PHP has fundamental flaws and that causes sadness, not this crap.)
What makes me sad is that even though I feel affronted by PHP's crudeness, inelegance and inconsistencies… I keep using it for a lack of another language that suits me personally.
I hate PHP's runtime and core libraries. But I really like the C-inspired syntax. I use Objective-C as my main other language, and something about Ruby and Python's syntaxes seem to rub me the wrong way. I'm giving Node.JS a whirl these days—and while I might be able to get used to closures everywhere, I don't know how to feel about the lack of true object orientation.
there's something wrong with the == and coercion in the if() statement in any language.
making the switch in if() be a boolean only pushes the problem off to the programmer, who will often choose the wrong function or expression to do the conversion
Resolving arrays like that causes parse errors in a range of contexts. Anything that is a "function" cannot also pick one array key... leaving a lot of XML-parsing code that looks like
$xml = getXpathWhatever();
$xml = $xml[0];
Stranger yet, is that it works perfectly fine with resolving objects... for example
[+] [-] larrik|15 years ago|reply
This happens to me while producing something like a jqGrid, or other javascript/html hybrid stuff that need a few extra options sometimes.
Django/Python? No problem! Just use the keywords you need.
(More Info: The difference between a single associative param standing in for keywords arguments, or a huge list of regular arguments is a choice in complexity/readability IN the function vs. calling it.
For the single dictionary approach, you lost the built-in parameter defaults nicety, which means you need to handle the case of a missing parameter manually. This kind of sucks, especially if you hate seeing PHP Notices during development (which kill JSON/XML output anyway). This makes your function often twice as big (or more) than it needs to be.
For the other approach, you wind up with calling
which just about invites all sorts of hard-to-find bugs, and you have to look at the function definition every time you want to change an option. Also, it's flat-out rude if you aren't the one calling the function.)[+] [-] dexen|15 years ago|reply
Nb., extract() works on any associative array, you don't have to use compact().
[+] [-] steve-howard|15 years ago|reply
[+] [-] shaunxcode|15 years ago|reply
In a nut shell though it's essentially a write up of my library which allows for creating keyword function wrappers so you can do stuff like:
[+] [-] blake8086|15 years ago|reply
[+] [-] pornel|15 years ago|reply
Use protected for overridable methods. You shouldn't mock or directly test private methods in unit tests — they're not part of the interface!
[+] [-] jrockway|15 years ago|reply
Come to think of it... public/protected/private is a dumb idea in C++ and Java, too.
[+] [-] mrspandex|15 years ago|reply
[+] [-] programminggeek|15 years ago|reply
These all seem to be sane critiques of PHP without being all doomsday world-ending inflamatory. Kudos.
Also, I think that this is another example of how hard it is to build up a large and widely-used language/framework without having lots of warts. Especially since PHP wasn't originally designed with the intention of powering everything from a simple blog/cms to facebook.
[+] [-] iphoneedbot|15 years ago|reply
[+] [-] thinkcomp|15 years ago|reply
[+] [-] alanh|15 years ago|reply
Still, glad I’m not doing much PHP anymore.
[+] [-] p4bl0|15 years ago|reply
[1] https://wiki.php.net/rfc/improved-parser-error-message
[2] http://news.php.net/php.internals/52436
[+] [-] koenigdavidmj|15 years ago|reply
[+] [-] lox|15 years ago|reply
[+] [-] user24|15 years ago|reply
not at all. A google search for "Paamayim Nekudotayim" gives you thousands of pages relating to exactly the error you're experiencing. It's WAY more useful than "Illegal operation" or "Syntax error".
[+] [-] qeorge|15 years ago|reply
Pretend that English had no representation of an ellipsis, but Hebrew did. Should the language author say "Expected: dot-dot-dot" in the error message to appease native English speakers, or should (s)he use the unambiguous form?
[+] [-] gergles|15 years ago|reply
http://www.php.net/manual/en/types.comparisons.php
We then have === which does what == is really supposed to do, but even that still sometimes does the Wrong Thing.
[+] [-] danudey|15 years ago|reply
This sort of 'well, close enough' behaviour has bitten me in the past as well. While writing a JSON bridge between an older PHP backend system and a newer Rails frontend, we kept getting exceptions on the Rails end.
It turns out that the JSON library uses isnumeric() to determine if a value is a number or not - which makes sense, in some respects. The problem is that we had a parameter (the external vendor's product SKU) which was a string that, in some cases, consisted entirely of digits. On those few occasions, the JSON library would say 'Oh, this is a number' and encode it as such in the JSON.
When Rails tried to unpack it, we got an exception because our Rails model was validating the data on the remote end and choked on getting an integer instead of a string.
We ended up having to actually modify the JSON library we were using (everything else we tried either didn't work or had the same bug) to modify the check. Completely ridiculous.
[+] [-] qntm|15 years ago|reply
I want to make sure that object A and object B are instances of the same class. Also, I want to make sure that they are equal i.e. that every attribute is equal. Also, since I'm now used to always using === instead of == for such comparisons, I use === to make the comparison. I would think that == would perform an == comparison on every attribute, whereas === would perform an === comparison on every attribute.
Nope! Using === actually verifies that the A and B are in fact references to the same object in memory, just like the "is" operator in Python. Got me again, PHP! How do I do my === comparison? Manually, that's how!
[+] [-] gergles|15 years ago|reply
"php" == 0 returns true, and this makes sense how?
[+] [-] wvenable|15 years ago|reply
I do a lot of PHP development but not exclusively and rarely does these sorts of deficiencies in PHP ultimately matter.
[+] [-] jwatzman|15 years ago|reply
[+] [-] unfletch|15 years ago|reply
I had it a little wrong in the initial report, but it was cleared up in the comments. The reluctance to fix stuff like this because "people might use this for some weird reason" is one of the reasons I'm glad I don't write much PHP anymore.
[+] [-] pornel|15 years ago|reply
[+] [-] jrockway|15 years ago|reply
The parser emits weird error messages because it is a very simple yacc grammar. (And because they turn off yacc's "produce better error messages" mode.) If you want good error messages, it's going to cost you -- just read perl's toke.c if you don't believe me. Good error messages cost a lot.
[+] [-] ckoning|15 years ago|reply
[+] [-] cgranade|15 years ago|reply
[+] [-] nimrody|15 years ago|reply
It's the one thing I hate about SciPy.
Passing by reference for performance reasons should be automatically handled by the compiler. I.e., A=sort(A) should be handled in-place without requiring a new function sort!(A).
[+] [-] eru|15 years ago|reply
[+] [-] shuzchen|15 years ago|reply
[+] [-] ars|15 years ago|reply
I clicked on a random item - the complaint that explode() doesn't take the empty string and return an array of each letter. But of course you can just use the str_split() function to do that (which is way more logical than passing an empty string).
So how do I contact the author and reduce his sadness level?
Or is this one of those websites that don't want to remove items, even if they are wrong?
[+] [-] stevep98|15 years ago|reply
implode — Join array elements with a string
string implode ( string $glue , array $pieces )
Note:
implode() can, for historical reasons, accept its parameters in either order.
WTF! What other library has a major function which doesn't care about the parameter order? It goes against every notion of good design.
http://us.php.net/manual/en/function.implode.php
[+] [-] betageek|15 years ago|reply
[+] [-] PaulHoule|15 years ago|reply
a total idiot can install PHP and get a system that will meet the performance and reliability needs of 99.5 of web sites out there.
tomcat, mod_perl, the ten different ways people host Ruby sites and all that make a lot more trouble for you. I've run PHP-based web servers for hundreds of sites that have served billions and billions of hits over the years and never once had to restart Apache because an application server got lodged. read that again because if you skip it, you're sysadminning blub.
every other system requires that you make choices, and the truth about choices is that faced with a binary choice there are two common outcomes: (i) a person freezes up like a deer in the headlights or (ii) a person makes a random choice that they're 50% likely to get right. (i)'s probably the better option.
i can complain about things wrong with PHP forever and i've got plenty of reasons to get off the PHP train. however, if you want to kill PHP, it's not enough to attack what's wrong with PHP, you've got attack what's right with PHP... You've got to make a better PHP than PHP.
[+] [-] DCoder|15 years ago|reply
[+] [-] sparkygoblue|15 years ago|reply
[+] [-] ryan-allen|15 years ago|reply
[+] [-] jessedhillon|15 years ago|reply
(Also, what if the length argument is dynamically generated, say from the size of a file?)
[+] [-] Androsynth|15 years ago|reply
It seems like the only point of having threads like this is for the leet programmers to look down on php. What's the point? This isn't constructive, its condescending and back-patting.
(the reason this makes me mad is that the sadness list is just a bunch of minor gripes. Every language has minor problems. PHP has fundamental flaws and that causes sadness, not this crap.)
[+] [-] SeoxyS|15 years ago|reply
I hate PHP's runtime and core libraries. But I really like the C-inspired syntax. I use Objective-C as my main other language, and something about Ruby and Python's syntaxes seem to rub me the wrong way. I'm giving Node.JS a whirl these days—and while I might be able to get used to closures everywhere, I don't know how to feel about the lack of true object orientation.
[+] [-] gburt|15 years ago|reply
http://ca.php.net/empty
-----
The following things are considered to be empty:
- "" (an empty string)
- [...]
--> "0" (0 as a string) <--
- [...]
- var $var; (a variable declared, but without a value in a class)
-----
Why the heck is "0" considered empty?
[+] [-] PaulHoule|15 years ago|reply
making the switch in if() be a boolean only pushes the problem off to the programmer, who will often choose the wrong function or expression to do the conversion
[+] [-] code_duck|15 years ago|reply
[+] [-] jcampbell1|15 years ago|reply
[+] [-] gburt|15 years ago|reply
$xml = getXpathWhatever(); $xml = $xml[0];
Stranger yet, is that it works perfectly fine with resolving objects... for example
$xml = funct()->something->somethingelse()->a
Works fine...