> Strict-equals on objects compares the references; but regular equals compares the contents of the objects. Two objects compare equal if the contain exactly the same fields and values. Seems pretty reasonable to me.

The line you quoted is talking about ordering, not equality.

> This is a good thing; JavaScript gets this wrong.

It IS a good thing, but it stands out when most of the language is extremely weakly-typed and even the original manual claims that separate operators for strings and numbers are confusing.

> I'm not sure if I understand this but all objects are passed-by-reference in PHP (since 5) and PHP references act appropriately when used as function parameters, etc.

So some things (objects) are passed by reference implicitly, and some (all else) are not. Yikes!

> You can declare constants in classes and namespaces with the const keyword.

Okay. Why not at top-level?

> You can cast scalars to single element arrays and objects to arrays with the same structure. Both are actually very useful.

You've practically invented a bug right there: if I write a function that can take either one value or an array of items, and you pass in a single object, I'll get a useless keyed array of its attributes.

> PHP is interpreted -- namespaces and autoloaders are PHP's module system.

What does being interpreted have to do with anything? Python and Perl are bytecode-interpreted (not positive about Ruby) and they both have rich module systems that don't require any fussing around. Heck, shell is interpreted, but zsh manages something almost like modules.

> Empty is equivalent to the not operator but will also work on undefined variables -- that's why it requires a variable.

Why does it need to look like a function when it clearly isn't one? return and echo don't.

> Useful inside of templates where matching { } is much more difficult.

In theory, but I've never seen any actual PHP code that uses them.

> Sometimes you don't care if a function succeeds; like with the unlink() function which will raise an error if the file you're trying to delete doesn't exist.

That's what exception handling is for -- unfortunately, PHP errors are an entirely separate beast from PHP exceptions.

> Not true. Debug_backtrace() will give you a stack trace in an error handler.

I said "PHP errors don't provide stack traces", and you aren't disputing that. Your own code can muck around to give you a stack trace (in most cases), yes, but the runtime doesn't do it for you.

> Assuming, of course, the programmer doesn't do anything to handle errors.

Defaults are important. I sure have a lot of people telling me it's great that PHP does web stuff out of the box -- why is it not then bad that PHP doesn't help you fix errors out of the box?

> E_STRICT (or lack of it) is for compatibility with PHP4. When enabled it will "warn you about code usage which is deprecated or which may not be future-proof." -- quote from the manual.

Yes, and that doesn't describe what it does. You can't tell what it's for, either: it's clearly not for compatibility with just PHP4, because even the PHP 5.4 release notes mention the addition of a new E_STRICT. Yet I can't be sure on what parts of the language actually ARE deprecated without reading the entire manual looking for mentions of E_STRICT.

> This author is confused why syntax errors would be parse errors but logic errors are not.

Read more carefully; the two lists are written roughly in parallel. A bogus object attribute gets a warning, but a bogus class attribute is a fatal error. (Not an exception, either, so you can't catch it with the exception handling that the OO system is supposed to be using.) A string value stored in a variable can be called, but the same string value as a literal cannot. And so on.

> This is sort of true; PHP errors and exceptions exist in different universes but it's easy to unify them and PHP even provides a built-in exception ErrorException to do so. You can turn every PHP error into an exception with 4 lines of code complete with stack traces.

Neat, though my understanding is that this still doesn't work with fatal errors, which are shockingly common.

I have the same kind of complaints about Perl's exception handling -- it's entirely possible to hack it into something more useful, but why on Earth should I have to mess around just to make something as fundamental as errors be developer-friendly?

> PHP supports both procedural and OO programming styles -- this is not a bad thing.

Exception handling isn't inherently OO. Perl has its own flavor of try/catch that requires zero objects whatsoever.

> PHP is reference counted with a cycle-detecting GC. That would not leak memory.

I believe it used to, but I removed this due to the short window during which it was a bug. I see this list of counter-arguments hasn't been updated in a while.

> This is true, but it's an ongoing discussion on how to correctly handle scalar type hints. For all the discussion about how PHP isn't designed the author takes issue with the thing they're taking their time on.

My issue isn't that they're taking their time, but that they implement half of a feature and then decide to sit down and think about the other half (while now constrained by whatever hack job they've already done).

> Because of the dynamic abilities of PHP, there is simply no way for the interpreter to ever figure out the variable to close over.

Every other dynamic language ever sure seems to be able to get this right.

> C++ does it. $obj::foo doesn't make any sense, if you're accessing class attributes then you use the class name Class::foo.

Then why not use Class->foo? Why does this need two operators? $obj::foo is perfectly reasonable if I want the foo attribute of whatever class $obj is; that's half the reason I ever use class attributes.

> This is personal taste not a valid critique.

Yes, which is why I said it's personal taste. Regardless, it's still wildly inconsistent with the rest of the language and poorly bolted on.

> That is, in fact, the point. PHP is supposed to be a thin scripting language layer over C. It's expanded beyond that. Many of the poor naming conventions are not because of PHP but rather are the exact API of the underlying C library.

How many people using PHP today came from C, exactly?

> Both the C API and PHP have both these functions for backwards compatibility reasons.

No. The C API has two functions because one takes only a value to escape, and the other takes both a value and a connection pointer. Both functions in PHP can be called with merely a value, and the "real" one will use the current global connection. Zend could have merely switched the old escape function to have the new behavior, and all existing code would have been instantly fixed, not broken.

> Most of these are provided by frameworks just as they are in Python, Ruby, C#, etc.

PHP is praised for its web features, but is missing a whole pile of functionality instrumental for actually writing nontrivial web applications. Either judge PHP only by the core language, or judge everything else by what you get with frameworks.