What are the crawling horrors of PHP?
quora.com
quora.com
> # Arrays and hashes treated as the same type
We like this! More specifically, there is no "array"; they are manufactured as dictionaries with integer keys. In practice this works fine, and it's not even algorithmically different, since a hash access is a constant time operation.
> Hash syntax versus class syntax - i.e. $key['value'] versus $key->value
We like this a lot! $array['key'] will access a dictionary. We know it's not going to go through things like subclass rules and overrides, the way an access would in JavaScript, avoiding one of the worst parts of the language, including having to use "hasOwnProperty" for rigorous code.
> # Functions/methods always require parenthesis
Yes, and it's really not clear to me that the "cure" is better than the disease here, and this comment seems a little out to lunch. The standard practice I would think would be to not expose a $person->first_name variable directly in the first place. If you want an object with a flexible key-value coding system, you're free to write one. (And you can override dictionary access [] if you like.)
> No macros
I tremble.
> Writing an array literal requires literally writing out the characters a, r, r, a, y, ( and ).
Oh boo-hoo. Comments like like this, to me, separate out perfectly the programmers who are interested in getting something done versus seeking a sort of pursuit of academic idealism for its own sake. I can tell he only just managed to resist saying it has braces and semicolons too.
> It depends what version of PHP.
Use PHP 5.
> How do you delimit HTML from output PHP code? <?, ?>, <?php ?>, <% %>? Well, it depends on some global setting in php.ini.
Use <?php ?> always.
> PHP doesn't have multiple inheritance, fine, but it doesn't have mixins/modules, either.
We do not want! Locality of code is worth more to us, especially for those of us who have tried to navigate a maze of categories in an unfamiliar Objective-C codebase or something like that.
> If you do enable PHP's E_ALL warnings, you get warnings and errors for all kinds of crazy things you don't want warnings for.
You're wrong, you really do want those warnings. If you want to turn off deprecated warnings for legacy PHP4 code, you should make that explicit.
> PHP is exceptionally slow unless you install a bytecode cache such as APC or eAccelerator.
So when it isn't fast enough by default (and it usually is), do that.
> People often abuse include(). Rather than using it to pull in functions and classes, they use include for actual code execution,
Like in a template mechanism, which is a legitimate use for it.
> Because it is designed to be run in the context of Apache, PHP doesn't work very well as a command-line scripting language,
A hammer doesn't drive screws very well.
> There is a lack of standards and conventions.
This is called flexibility. You can code within CakePHP or Zend Framework if you want conventions.
> There are a variety of ORMs available all of which suck in different ways,
This is not just a PHP problem:)
Maybe you do. But I've always found it annoying.
> In practice this works fine, and it's not even algorithmically different, since a hash access is a constant time operation.
It is actually. Read the array.c and zend_hash.c code. It's only a constant time operation if you're not interested in the difference between whether a hash key actually exists, or whether it exists and its value is set to NULL. The former is O(n) if you use array_key_exists. From zend_hash_exists:
while (p != NULL) {
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
if (!memcmp(p->arKey, arKey, nKeyLength)) {
return 1;
}
}
p = p->pNext;
}
return 0;
>> PHP doesn't have multiple inheritance, fine, but it doesn't have mixins/modules, either.> We do not want! Locality of code is worth more to us
Code that I'd write in Common Lisp or Perl that takes advantage of multiple inheritance and the composition it offers is a lot uglier in PHP when I have to hack around not having multiple inheritance. It leads to bigger and monolithic classes that you can't easily compose.
>> Because it is designed to be run in the context of Apache, PHP doesn't work very well as a command-line scripting language,
> A hammer doesn't drive screws very well
This is actually a major problem with PHP. Unlike Perl, Python, Ruby, Lisp etc. you can't easily run most PHP code persistently, so the execution model for most applications is to parse, compile and execute the application for each request.
You can get around that in some cases, but some core language features have been blocking this until relatively recently. E.g. create_function() would always leak memory, but in 5.3 PHP finally has support for anonymous functions.
That's weird, and does seem like a wart. But is this really a problem in practice that leads to performance difficulties in real code? (This is not a snippy rhetorical question, I'd be interested in a real world example.) It seems to me that if I'm using a PHP dictionary as an array, I'd know the length, and thus I'd be guaranteed that any access exists.
I also like that arrays being dictionaries gives me the ability to do foreach($array as $index=>$value) if I want, which is nicer than some other languages, though admittedly some dynamic languages do such things better.
> Code that I'd write in Common Lisp or Perl that takes advantage of multiple inheritance and the composition it offers is a lot uglier in PHP when I have to hack around not having multiple inheritance. It leads to bigger and monolithic classes that you can't easily compose.
This is a holy war, obviously, and you do get interfaces at least. It suffices to me to know that I do have some intelligent supporters on the side of disliking multiple inheritance and mixins very much. If you're one of the people who can be extremely productive building large programs in a Lisp style, much respect and power goes to you, and anyone has to concede that PHP will be too limiting in that case.
> This is actually a major problem with PHP. Unlike Perl, Python, Ruby, Lisp etc. you can't easily run most PHP code persistently, so the execution model for most applications is to parse, compile and execute the application for each request.
Agreed, and it is a huge pain when you want to do something after a request but yet you don't want to tie up the user in the mean time.
I'm not sure I'd want PHP to be a language that makes it easy to have a persistent execution model though; that simplicity (and restriction) is one of the things that has made the language so popular and scalable. PHP's model usually works fine for the kind of web-based problems it's intended for.
Here's some code I wrote in 2005 that ran into this issue: http://www.mediawiki.org/wiki/Special:Code/MediaWiki/10549
> It seems to me that if I'm using a PHP dictionary as an array, I'd know the length, and thus I'd be guaranteed that any access exists.
The use case is the common idiom of populating a hash, and then iterating other hashes and checking if their keys exist in the original.
In the example above I was loading ~50 files with 1000 key hashes each to check if there were any leftover translation strings in the translated files that weren't in the English original.
Because the values could never be NULL I could get away with not using array_key_exists() which reduced the runtime from 60 to 2 seconds. But it's pretty silly that the core datastructures of the language have pitfalls like these.
>> This is actually a major problem [...]
> Agreed, and it is a huge pain when you want to do something after a request but yet you don't want to tie up the user in the mean time.
> I'm not sure I'd want PHP to be a language that makes it easy to have a persistent execution model though; that simplicity (and restriction) is one of the things that has made the language so popular and scalable. PHP's model usually works fine for the kind of web-based problems it's intended for.
In some ways, especially the built-in template language. But overall I think PHP as a isn't simple or newbie friendly at all. Its main advantage was that it offered a really simple execution model + Apache module. Which ISPs and others could easily offer along with MySQL, with little administration time compared to offering equivalent shell services.
It was also was one of the first to have friendly online documentation with lots of syntax highlighted example code, and comments where people could submit more examples.
But as a language it was never very competitive, and due to some of the tradeoffs made PHP never acquired a real community of module writers and re-usability. Thus most large PHP code bases end up being big balls of mud compared to equivalent code written with Catalyst, Django or even Rails.
These days it seems to be mostly heading for being a worse Java with more bugs. Unless you have existing code in PHP other languages are probably a better fit for web applications these days.
He doesn't like the lack of strict mode, but complains that E_ALL tells him too much; maybe it's telling him too much because he's not writing things correctly, just like 'use strict' would.
He complains that you need to remember the parenthesis for a function call, but short of Ruby, I can't think of any other "normal" language that doesn't. C/C++/C#, Java, Python...
He complains that a whole bunch of things are considered false, but when using the === operator, they aren't.
Always use <?php ?>, and your code will always work, everywhere.
Just because people abuse include() doesn't make it a flaw of the language. Strawman ftw.
Plugins written for one framework won't work in another. Gasp! News at 11...
"use strict" makes compilation errors. E_ALL only does runtime errors. Both are useful, and having one is no excuse for missing the other.
As a note, they complaints seems to mostly be about the lack of standards and conventions. I can agree with that issue, if they find a way to make the standards and convention better.
http://terrychay.com/article/hiphop-for-faster-php.shtml/4
One of the things that really surprised me was the observation that PHP has a much higher CPU utilization for comparable operations than other higher level languages.
All this kind of thing tends to do is embolden the snobs, put the backs up of the faithful and be of no practical use to any reasonable person looking for honest answers. It doesn't even have the virtue of being a humourous discussion since it's been flogged to death over the whole internet for a decade.
I think the far bigger problem with PHP comes from the culture that surrounds re-use. Writing re-usable PHP is hard, we lack decent package management systems and systems for distributing light-weight packages of code with simple dependancies (I'm looking at you PEAR).
The end result is a culture where re-inventing the wheel is standard practice or at best copy and paste.
>>> def some_func(a=1, b=2, c=3):
return (a + b) * c
>>> val1 = some_func()
>>> val1
9
>>> val2 = some_func(b=3)
>>> val2
12
>>> val3 = some_func(c=5)
>>> val3
15
>>>I don't know all libraries on CPAN that implement some kind of function signature or argument validation, but I can't remember seeing one that requires ordered named arguments.
For me this is an advantage over other languages. I'm looking at you, Perl.
PHP has a Frankensteinian mix between the two. You /can/ implement it in any other language by just keeping an array along with your hash that indicates the order in which elements were inserted: http://search.cpan.org/perldoc?Tie::StoredOrderHash
But you almost never want to do this. I've only used it once in all the PHP code I've written. And having to deal with the ambiguity of PHP's key-value array datatype wasn't worth it elsewhere wasn't worth that.
This 'Frankensteinian mix' is the most versatile collection type I have seen so far and I attribute large part of PHP success to having this as first choice when in need to keep collection of elements.
You can build vector, list, stack, tree, map without even knowing what those are just confronting what abilities you require with what PHP arrays can do.
However, other than that I don't have problems with PHP's "arrays".
I find ordered key-value datatype very useful in lots of situations — all kinds of mappings ordered by priority, queues where you can remove any item quickly, trees where order matters (e.g. stuff coming from XML).
Sometimes even in cases where order doesn't strictly matter, preserving order makes operations more predictable and results easier to compare (e.g. you can load ini file to PHP "array", edit and save, and it won't get shuffled).
It might be a matter of how you think about your data: whether you think of it as arrays and hashes and try to retrofit it in PHP, or whether you think of mapping it into PHP's peculiar "array" from the start.
* Yeah, Lua is 1-indexed. Ah well.
my @array;
# $#array : number of @array elements
say $#array ; # print -1
$array[10]=3;
say $#array; # print 10
But it is quite common to populate an array, then delete some elements in it for instance.Anyway, the actual use case of populating an array and then deleting some elements works fine in PHP; I don't think there's any difficulty with expressing what you want -- it's just going to be somewhat less efficient than it could be. In your example, it's not clear to me what indexes zero through nine point to... null, maybe? In PHP, you'd have to be explicit about what values you wanted in zero through nine by using array_fill(), or live with:
for($i=0;$i<=10;$i++) {
if(!isset($array[$i])) continue;
// ...
}
If you use a for loop, you'd have to check each value to make sure it's defined like that. If you don't care about order in the loop, you could use foreach and avoid the check and a lot of extraneous looping.Several years ago I wrote a feature simultaneously in Python, Perl, and PHP. It was a fairly simple task-- retrieve a list of formatted strings, parse the data with regular expressions, and transform the 3-dimensional information into a 2-dimensional table.
In the python version, the regexp functions were ugly, but idiomatic and also separated into independent functions. The logic was clear and 3 years later it's still easy to understand what it's doing.
I can't find the perl version, but I remember having to use a retarded workaround because references weren't working as documented in one tiny (but essential) edge case. Basically I had to duplicate the entire program to handle two different cases. There is was probably some completely different strategy that would work better, but I didn't have three days to spend digging through perl docs to find it.
In the PHP version, I seem to have had some trouble using abstractions. The program is just one monolithic while loop with some comments. Also, I see some weird hacks in the PHP version and I don't remember why I had to use all of them. At one point I'm populating an array with empty values using 'array_fill()' and I see some temporary-looking variable names like $start_end, and there are a bunch of comparisons to arbitrary index values. For example $start_end[1] is 'start' and $start_end[2] is 'end'. There's none of this crap in the python version.
Ultimately I went with the PHP version. Because the rest of the app was already written in PHP it was far easier to deploy. A year later the feature broke for some reason and I never had the time to fix it.
So ultimately, I would probably tend to avoid PHP in the future because it doesn't seem to support my style of programming very well and I don't see many advantages to indoctrinating myself to its quirks.
For me this was a show stopper for using PHP for anything other than maintaining existing stuff that we inherit (and only for clients we really like).
error handling is at its core a foundation to quality, without proper error handling you have to put in significant effort to build a quality product because the structure has to be reinforced at every level. Having multiple ways to handle errors is almost worse than having none at all. This is one area that really needs to be standardized and have "the one way" to do it. Good or bad, it allows everyone to know what to expect.
It is just my opinion but, this one flaw makes PHP one of the worst languages I have ever use, which is sad because Wordpress and Drupal are great products but I can't stand to have to work in PHP, if I have a project that I know will not require custom development, I use Wordpress or Drupal I really wish they supported alternative languages for writing custom modules,It would be nice to be able to write them in Python or hell even JavaScript has proper error handling.
Oh wait. That's true for (almost?) all languages that are used to writing webapps.
This is a complaint I'v made before... Currently I am using Jelly [1] for the Kohana framework and it is wonderful compared to most of the PHP ORM offerings.
Here are the behaviours: http://github.com/jonathangeiger/kohana-jelly/tree/master/cl...
I once wrote a crawler loosely based off Snoopy (http://snoopy.sourceforge.net/) and it was a nightmare.
"I'm not a real programmer. I throw together things until it works then I move on. The real programmers will say 'yeah it works but you're leaking memory everywhere. Perhaps we should fix that.' I'll just restart apache every 10 requests."
But because that could sound like either DHH or Rasmus Lerdorf, there's also this:
"I have absolutely no idea how to write a programming language, I just kept adding the next logical step on the way."
The lack of overall direction and ball-o-mud hackery is exactly what one would expect to underlie PHP in its present state.