Still, glad I’m not doing much PHP anymore.
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".
> It's WAY more useful than "Illegal operation" or "Syntax error".
Wut."Syntax error on line 14" -- Okay, time to look at line 14 for a mistyped semicolon or something. These two words Mean Something.
"Unexpected T_PAAMAYIM_NEKUDOTAYIM on line 14" -- means absolutely nothing unless you've already looked it up. It's essentially easily-googleable nonsense. It might as well say "Error 0x444F808E". You can google that, too, and it also tells you nothing useful.
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?
This isn't about whether we use English or not, or whether that's the right choice or not, it's about consistency. If you want to create a language that has all-Hebrew tokens and error messages, knock yourself out. Just do it consistently.
IMO, that would only be a good idea when taking part in a obfuscated programming language context.
Yes. It's not about appeasement, it's about consistency.
Use protected for overridable methods. You shouldn't mock or directly test private methods in unit tests — they're not part of the interface!
Come to think of it... public/protected/private is a dumb idea in C++ and Java, too.
PHP is mostly a static language; it has more in common with Java than with say Ruby.
> prefix it with an underscore
Oh god, really. Next you'll be telling us we don't need namespaces, we can just use an underscore as a separator!
> 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.
Or you could just build that all into the language itself so it's self documenting and provides a nice concise error message when used incorrectly!
I'm amazed that people would argue for naming conventions over actual features. Hell, nobody is saying you have have to use it; if you'd rather use underscores the languages will let you.
Dynamic or not, objects have interfaces and this is a way of defining the public interface and catching violations of it.
> Easier to maintain, easier to test, less code to type in
My impression is opposite. They add friction to changing visibility. I like to start with everything private and then unprotect as needed.
It's extra character to type and it interferes with autocomplete.
Accessibility of "private" methods shouldn't be help in tests — you'll end up creating tests that depend on implementation. If class is too impenetrable to test, then refactor it (split concerns, add dependency injection, etc.), don't unprotect it.
I think the worst villains of the public/protected/private family are getter/setter methods, it bugs me when I see them in Python code. We use enunciate ( http://enunciate.codehaus.org ) at work, and we bundle AMF endpoints with our stuff. Unfortunately the Java-to-actionscript step complained when our data objects don't have getters/setters (since I like just using public attributes), so now I have two Python scripts: one generating the Java code for a data object along with annotations, the other adding getter/setter methods.
Other than that it smells like a variation of the singleton antipattern.
In the same release, they decided to finally add namespaces. But, despite the tired claim that PHP takes cues from C/C++/Java, they did not reuse :: (aka paamayim nekudotayim) as the scope resolution operator. Instead, they devised a new operator: '\'.
There is an IRC log somewhere where you can read the painful arguments back and forth over what this operator should have been. One of the rationalizations for the backslash was that it makes sense to Windows developers, as they are already familiar with the idea of '\' being used to separate elements of a hierarchy.
The end result:
Java:
Attribute/Method access: foo.bar
Static method access: Foo.bar
Package access: foo.bar.baz
C#:
Attribute/Method access: foo.bar
Static method access: Foo.bar
Namespace access: foo.bar.baz
Python:
Attribute/Method access: foo.bar
Static method access: Foo.bar
Module access: foo.bar.baz
PHP:
Attribute/Method access: $foo->bar
Static method access: Foo::bar
Namespace access: foo\bar\baz
> Who, after five major releases, decides that what a language really needs is `goto`.
It makes it a much easier compilation target.
> But, despite the tired claim that PHP takes cues from C/C++/Java, they did not reuse ::
They couldn't because unlike C/C++/Java the entire project isn't compiled at once. At compile time, PHP has no idea that the symbol preceding the operator is a class name or namespace from one run to the next. It might have been possible to resolve that with major changes to the underlying engine or maybe not. I absolutely hated the idea of the backslash when proposed but after using it for a while it seems fairly comfortable.
In general, some aspects of PHP will not be fixed/improved for reasons of either:
* backward compatibility, or
* incompatibility with the vision of the language by the core dev team.
http://marc.info/?t=121142259100001&r=1&w=2 http://marc.info/?t=119995974300003&r=1&w=2
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.) $foo = 123;
$bar = getSomeBar();
myFunction(compact('foo', 'bar'));
function myFunction($kwargs) {
$foo = SOME_DEFAULT_VALUE;
extract($kwargs);
if ($foo > 5) {
...
}
}
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().
myFunction($parms=array()) {
...
}
$parms = array('foo' => 'bar',
'baz' => 'yaz');
test($parms); do_something(@$_GET['foobar']);
There are ways to suppress PHP notices without just turning off the E_NOTICE output.It's also making the interpreter do unnecessary error handling work when a simple "if ($_GET['foobar'])" would suffice.
Instead, I use a 'get or else' function, as in some functional languages. For arrays, it goes
function get_or_else($array,$key,$default=null)
{ return isset($array[$key]) ? $array[$key] : $default; }
This avoids any warnings, and also allows you to specify a default.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:
myStrPos(
needle, 'peter',
haystack, 'is peter in here?'
);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.
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!
That PHP chooses not to try and provide a means of determining object equality is not a poor choice. Using the === operator to test whether two variables are references to the same object is then also not a poor choice.
"php" == 0 returns true, and this makes sense how?
"==" makes the comparison after converting types (see: Type Juggling in the docs) where "===" requires that the types be the same in order to be equal.
Kind of weird the first time you see it, but it's a language design choice and does make sense once you understand it.
Oh, and to demonstrate: "PHP has no native Unicode type, no native Unicode handling, and cannot treat Unicode strings as strings." This true statement, composed of three observations about deficiencies in the language, gets me flamed every time I mention it. Why?
perhaps because statement of of fact (``PHP has pluggable Unicode support'') beats wrong statement of oppinion (``PHP is bad because has no support for it''). It's borderline trolling to insist PHP does not, when people have been using it successfully in production for years now.
http://pl2.php.net/manual/en/book.mbstring.php in case your google is broken.
Here's a fun question: How do you strtok(), implode(), or explode() mbstrings?
Seems logical to me. These defenders are presumably professional PHP developers. They're presumably supporting their families by coding PHP. The more widely-spread the language is, the more it's used for new projects, the more lucrative and interesting their work will be.
And here you are, making a fuss, and many of these people may know ONLY PHP. And you're trying to argue that their most valuable skill should be put on the trash heap.
That's why THEY fight so hard: They're feeding themselves with the language.
Now, why do YOU fight so hard against them?
You can carve out a decent subset of PHP, but there's this painful and dangerous beginning and middle part where you're still learning this subset and in the meantime you're writing grossly insecure code. Perl has much the same problem. There are no languages I know where you are immediately writing brilliant code, but there's certainly ones you can learn faster, cut down the danger period, and also have many of the worst dangers ameliorated by much better design decisions at the API and language level. (How much of PHP and all similar languages would have been better if only the default interpolation HTML escaped everything and you had to especially ask for direct interpolation, instead of the other way around?)
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.
Coming from a PHP background, the first time I tried Django, I was rather dismayed at the amount of set up involved. I think after following a few tutorials, I was able to more or less get a running mod_WSGI setup, though the only way I could seem to get the web site to refresh was by restarting Apache.
After I got over the fear of using an http daemon written in the same language as my web app, I discovered Ruby / Sinatra, which gave me more or less the same immediacy I was used to from PHP.
Even so, I doubt I could explain Heroku to a non-technical friend in the same way I could convey an understanding of uploading a php web page to a LAMP host. (Ubuntu's broken support for RubyGems didn't do much to help my migration from PHP either).
It seems to me that until Python and Ruby have an infrastructure that's as friendly to novices as PHP is, we'll be seeing the same "PHP ghetto" effect that we've been seeing for the past decade.
This is like living in a house where the builders were "total idiots" and hammered in all the screws with a hammer instead of screwing them in with a screwdriver. Sure, it holds together. It might not even collapse in a light breeze.
But one day, you'll want to reshingle the roof, or there will be a thunderstorm, and then your house collapses, killing your entire family. Good engineering requires good implementation. PHP makes good implementations too hard.
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.
Theoretically, this is why you hire people with experience. They picked randomly the first time, and then gathered data. Their random choice either worked or it didn't. Repeat a few times and you have "senior system administrator" and "senior engineer" instead of "random dumbass we found on the street corner", and then this part of the equation goes away.
Now, if your goal is to produce something that sometimes works with the least amount of money possible... yes, you should outsource your development and deployment to some high school kids in India. If your goal is to produce something that works...
(Also, the days of PHP's deployment superiority are nearly over. With mongrel2, I can restart my app instances without losing a single request!)
I do not recall at any point in Beating the Averages [1] in which pg used "ease of installation" as part of the definition of a blub language.
Blub has a specific meaning. It's not a synonym for "bad".
There are plenty of other technologies that are as reliable as PHP. Ruby was not really one of them. Ruby went through a bad hype cycle a couple of years ago and was never quite as good as it was sold to be, especially on the reliability front. It's a great anecdote but a bad argument.
http://www.getrailo.com/com/index.cfm/whyrailo/developers/
(Scroll to bottom where they address why for PHP devs)
1. it exists
2. it's used
3. many of its users make more money than me
4. it has poisoned the market, clients have learned to expect and even demand php-braindeath
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).
-----
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?
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
What exactly is the alternative?
If there's any problem here it's automatic coercion.
function foo($arg1,$arg2) { return; }
foo('bar');
Warning: Missing argument 2 for foo()
Lame. But omitting arg2 is allowed if you give it a default value: function foo($arg1,$arg2=FALSE) { return; }
Blah. Instead I'd rather make arg2 truly optional just by testing if it's defined.If I don't require args: function foo($arg1=null, $arg2=null) {return;} foo(); // return no error
This is great for me, when I am writing an API and have some args that are required and others that are optional.
<?php
$foo = array("a", "b", "c");
foreach ($foo as &$bar)
echo $bar;
echo "\n";
foreach ($foo as $bar)
echo $bar;
echo "\n";
The "&" is a foreach-by-reference, for those not familiar with the language. When you think you've figured it out, you can execute the code at http://www.contrib.andrew.cmu.edu/~jwatzman/foreach.phpI 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.
unset($bar)
after the first loop is highly recommended.$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...
~/php_source/php-src-5.3$ ./sapi/cli/php -r "function a() { return array(1,2); } print a()[0];"
Parse error: syntax error, unexpected '[' in Command line code on line 1
~/php_source/php-src-5.4$ ./sapi/cli/php -r "function a() { return array(1,2); } print a()[0];"
1
$xml = reset(getXpathWhatever());
which returns the first element from array.
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.
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.
"Good error messages cost a lot" and "They turned off yacc's 'produce better error messages' mode" seem to contradict one another.
And no, in a lot of cases the parser emits weird error messages because the internal variables are named weird things. If you're telling me it's unreasonably difficult for PHP to produce a better error message than "Unexpected CONSTANT_NAME" than why name your constants unintuitively?
I do a lot of PHP development but not exclusively and rarely does these sorts of deficiencies in PHP ultimately matter.
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?
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.
foobar() is the same as FOOBAR()
$foobar is completely separate from $FOOBAR(Also, what if the length argument is dynamically generated, say from the size of a file?)
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.)
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.
Why would anyone writing a PHP app need those? The page just calls it a missing feature without explaining why this is a bad thing.
http://www.jwz.org/blog/2011/05/computational-feces/#comment...