"You can import classes from namespaces but you can't import functions."
IIRC one of the arguments for the \ namespace separator was that it would allow for namespacing functions. Someone (perhaps a few people) had demonstrated a :: separator namespace patch, but it would only work with classes, and it was felt that \ was the only legitimate option because it would allow namespacing of non-class code.
EDIT - I can't find refs online - I'd read that in a recap of the issue in PHPArchitect about 2 years ago.
Awesome...
"PEAR has been around since before PHP5's release in 2004 and there are 179 modules hosted at pear.php.net for 5.0+. (And only 19 for poor PEAR2 and PHP 5.3) Contrast with npm which has been around since August 2010 and hosts 6,157 packages."
I'm no fan of PEAR, but when people start showing off how many XYZ something else has, I always have to wonder if it's because the default/core/base platform doesn't provide much out of the box. And... hey - downloadable packaged code is fine and all that, but you run the risk of version hell pretty quickly. npm is, imo, already hitting that - more than 6 months ago all I wanted to do was download node and run vows and zombie. No dice - I lost count of the errors I hit trying to make that work because of some version incompatibilities.
I get your point, but java/ruby/node and other platforms with extensive third party library ecosystems can quickly become dependency nightmares.
Node.js and npm made a pretty vicious, backwards compatibility breaking change in its symbol loading algorithm in the move from 0.3 to 0.4. It was a weird and frustrating blip for those who were programming for node before that. What they now do with dependency management is pretty genius, since 0.4. Dependencies are installed locally to the package that depends on it, not globally on your system, and can be fulfilled recursively. Say you depend on Package B.1 and A.2, B.1 can simultaneously depend on A.1 and everything works out fine. It's perhaps the most interesting approach to the dependency problem I've seen (and, unfortunately, a system that couldn't be replicated in PHP without really shaking the foundation). (edits)
I don't doubt it's gotten better, but it's a bit of a case of 'once bitten twice shy' with me. I may come back at some point, but I've no pressing need atm to be playing with node.
I remember using CPAN for the first time and thinking it was magical. Like how they tell me the iPad is magical. Then a few years later using PEAR I suddenly felt the complete opposite.
I won't claim to know what the best alternative would look like, but I'd definitely take npm over PEAR any day.
I don't think PEAR caught on as well because PHP has been largely associated with cheap hosting services that didn't really give you access to a console that would let you use PEAR to it's full extent. Then you have to add in the fact that PHP doesn't really have a solid package management philosophy in the first place.
I think it has more to do with the usual background of each language's programmers. Perl coders (especially Back In The Day) tended to disproportionately come to Perl from systems administration backgrounds; package management is something that sysadmins are used to worrying about, so they created a strong culture of package management in Perl early on. PHPers on the other hand tend disproportionally to come from web design/HTML+CSS backgrounds, which haven't exposed them to the problems that a good package manager is designed to solve. So package management in PHP has never been a priority.
The long lack of namespacing probably hurt the adopting of package management in PHP but also it seems like overkill. I use an occasional PEAR package, but I always just download the source and integrate it into the project that way. It seems like more work to go through a package manager especially since I work on multiple different operating systems. It might also help that PHP packages tend to have very few dependencies.
I think it may seem like more work, but without strong package management things like reinventing the kitchen sink & copy pasta from various unreliable sources becomes the norm. You could almost say that the comments in the PHP manual were relied on more often than PEAR.
Although package management can cause it's own problems like dependency hell or multiple packages that do the same thing but none of them do it well.
> I get your point, but java/ruby/node and other platforms with extensive third party library ecosystems can quickly become dependency nightmares.
Actually, what I found sorely missing in php and started loving in the ruby world is bundler. It's not a package manager, but a dependency manager. You feed it a list of gems that you directly depend on and it figures out which gems to install in which versions so that all direct and indirect dependencies are satisfied. If it can't, it prints a meaningful error message. On top of that you can stack tools like gemnasium which track which of your dependencies were updated.
I do have a couple of projects that depend on about a hundred different gems. Managing that would be impossible without bundler. On the other hand, having a tool that enables you to manage this complexity makes you write smaller and smaller self-contained, separately testable gems that just add some little piece of functionality on top of some other lib or pulls together multiple libs and adds the glue code. It's actually common that even full-stack frameworks like rails or padrino consist of a handfull of separate pieces with another gem gluing them together. Even ORMs such as datamapper come in pieces.
I know of no tool in the php world that even attempts to solve this problem.
The PEAR maintainers seem to disagree with the direction PHP is going as a language, so they don't keep it up to date with changes in the language. If you want to use PEAR, you need to either hack the code yourself (why use PEAR) or you need to put PHP in an out-of-date compatibility mode.
It sounds to me like the author is trying to write php like he would use javascript.
existing php projects won't soon benefit from language features and new frameworks without significant rewrites, and their absence make php less attractive for the style of development he seems to favor.
The article's intention was to promote the idea that plain-old functions should have their place as an equal contemporary to classes. I'm mostly a fan of PHP's object model, it's more complex than it needs to be in some ways, but it works. I could write a similar article on JavaScript talking about how it needs to indoctrinate a class hierarchy paradigm. My understanding is there are talks of this happening in ECMA.next. But CoffeeScript's model is currently good enough for me.
Very interesting. How has this not gotten more attention? On first glance this is pretty much exactly what I was describing would be valuable. Are you the author?
Well, personally I wouldn't use it, because it doesn't look idiomatic enough.
PHP CMSes had package managers for years. It wouldn't hurt to look at them and learn what they did right and wrong before cloning Ruby/CPAN/NPM solutions.
I think Packagist/Composer is on the upswing, but it takes time to spread the word and change such a big/diverse/chaotic community. More prominent projects adopting it will help too :)
I'm a micro-php sympathizer, but I'm wondering if the pendulum isn't swinging a little too far in the other direction here. Import libraries function by function? Are there really no libraries that are small and address your needs with a minimum of cruft? If we don't want to import a simple router class, maybe the solution is to trim down the class, not break it up into discrete functions to be imported one by one. What would a more-than-small application look like like this? I fear it'd look crazy; but I'm just speculating.
Anyway, if you really want to import functions it's not like it's impossible.
echo "<?php function myFunk(){ echo 'hi'; }" > lib/myFunk.php
Then `require 'lib/myFunk.php';` I'm sure there are more graceful ways in other languages but this works. (EDIT: Namespaces notwithstanding ;)
The problem is that PHP is going through growing pains a 15+ year old language should have fixed years ago, but didn't.
Now there's too much atrocious code out there that would break with updates to PHP. I firmly believe PHP.next has to declare it's going to break everything, take all that we've learned now, and build a great web language that is easy to use.
This actually seems to be happening with a lot of the "old workhorse" style languages. Perl, PHP & Python all seem to be struggling with their reinventions.
Ideally, yes... though such a move would probably void most of the reasons for using PHP in the first place -- ubiquitous availability, and popular software that is built in PHP. Take those away, and mess with conventions that all the current PHP developers are used to, and why not just use another language?
PEAR has had a lot of issues, but recently the PEAR community is addressing them. For instance you do NOT have to deal with the PEAR process if you want to use PEAR to distribute your code. You may setup your own channel* and do whatever you please. Secondly PEAR is in the process of setting up it's packages at Github to make it a lot easier to collaborate on code.
I think these changes are great and PEAR's future is looking a lot brighter due to the people driving these changes.
*Personally I think it's a good idea to have some kind of vetting process in place. If you look at for instance the WordPress plugin repository as an example of a repository without it you'll notice loads of crappy plugins or abandoned code. I presume that with a vetting process (and maintainer process) one could prevent this from happening.
The process of adding channels and installing from them isn't too bad, but it's still additional friction. You can't do "pear search foo" and hope to find what you're looking for. Moving system-to-system you have to re-add all those remote channels you depend on.
Moving to Github is a good move. Opening up some sort of "PEAR commons" where the requirements aren't as arduous as PEAR proper would go a long way.
When package dependencies are tracked explicitly there's a very natural, Page-rank like effect that pushes the best, most reliable packages to the forefront because everyone depends on them. Just look at npm's "most depended on" list: http://search.npmjs.org/ You can look at any package and see what other packages depend on it.
PEAR's curation process feels a lot like Yahoo's of old's curated link database. npm's feels a lot like Google's "anyone can publish, we'll track dependencies, the good stuff will surface".
I think NPM is at the opposite end of the spectrum to PEAR. Just try figuring out what the standard Mongo or MySQL library is with NPM. I think there needs to be some level of curation and/or tiering of packages.
Honestly I learned about the PHP mongo extension by going to MongoDB's website & reading how to get it to work. My first thought was not to do 'pecl install mongo'. This probably has more to do with 10gen taking the effort to write a proper extension for PHP rather than letting the community come up with a module for node.js. Also I don't think node has had time to "settle" since it's still evolving, so you'll experience package fragmentation like what you see with mongo.
I do agree that along with package management there should be a strong community/social component involved that critiques & communicates about packages available.
npm's tracking of dependencies, and potentially downloads, could be used to help tier packages in search. You can currently see the most depended on packages, as well as the packages that depend on individual packages, but this could be taken further to help establish PageRank like authority.
The author nails it down. I have been doing functional PHP for many years now. I rarely need objects or classes. I don't like the direction where PHP is heading. Namespaces were nice, anonymous functions were nice, and short array syntax is nice. But I would like to see named parameters, function imports, namespaced constants, function overloading, more extensions, and JIT compilation (Facebook has already done the ground work). But I feel the interest with PHP core developers is to clone Java or .NET. It doesn't feel right to have huge PHP class libraries like Zend, Symfony, or Doctrine. PHP is glue! It's about hacking things nicely together. It's not enteprise stuff. Clean and simple.
I started using functions widely in an MVc framework. It began when Rails was released, and I thought, how could I copy the "helper" mechanism in a way that makes sense for PHP?
My answer was to use plain functions as helpers, at first because they could easily become Smarty modifiers, and later realized the function-only pattern worked really well across the whole app.
Note: I purposely called it MVc vs. MVC. The controller is minimized in favor of native REST access to models/resources. If anyone is curious about this, I'll be writing about the new convention soon.
This is a great point. I find PHP's movement towards things like PSR-0 just too verbose most of the time. There's a lot of plain function use in my work these days building a simpler/minimalist modern MVC framework (http://www.elefantcms.com), and despite naysaying from the OOPS camp, it works very well in practice.
Thanks! Making "handlers" feel like ordinary PHP scripts that execute top-down seems like the most natural way in PHP, since that's how the language itself works. It's not much different than inverting the require statement, your front controller includes your handler after initializing some helpers for you :)
It's not as "structured" as methods in a class that extends a Controller class, but it works just as well and eliminates a good bit of boilerplate code in the process. Also helps new developers get up to speed quickly I've found.
My one bit of criticism might be, in a plain php file without any code block wrapping handler logic, it's harder to understand context. I don't know exactly where this file is getting executed, and so it's not clear where the contextual properties are coming from? Perhaps that's the point.
It's definitely a possibility! That would mostly just be a matter of removing the default apps and layouts, then cleaning up the configs that pertain to the CMS. Would make a fun weekend project :)
Releasing the framework separately would take care not to add confusion to the documentation side of things. Then again, having a separate 'elefant-core' project that the CMS builds on may even help...
The problem with PSR-0 is that it requires a one file per class approach. You end up with way too many files where you can create beautiful single file packages with just a namespace at the top and a series of classes in the file.
40 comments
[ 4.1 ms ] story [ 94.8 ms ] threadIIRC one of the arguments for the \ namespace separator was that it would allow for namespacing functions. Someone (perhaps a few people) had demonstrated a :: separator namespace patch, but it would only work with classes, and it was felt that \ was the only legitimate option because it would allow namespacing of non-class code.
EDIT - I can't find refs online - I'd read that in a recap of the issue in PHPArchitect about 2 years ago.
Awesome...
"PEAR has been around since before PHP5's release in 2004 and there are 179 modules hosted at pear.php.net for 5.0+. (And only 19 for poor PEAR2 and PHP 5.3) Contrast with npm which has been around since August 2010 and hosts 6,157 packages."
I'm no fan of PEAR, but when people start showing off how many XYZ something else has, I always have to wonder if it's because the default/core/base platform doesn't provide much out of the box. And... hey - downloadable packaged code is fine and all that, but you run the risk of version hell pretty quickly. npm is, imo, already hitting that - more than 6 months ago all I wanted to do was download node and run vows and zombie. No dice - I lost count of the errors I hit trying to make that work because of some version incompatibilities.
I get your point, but java/ruby/node and other platforms with extensive third party library ecosystems can quickly become dependency nightmares.
Here's a link to the node_modules loading algorithm since v0.4, if you haven't checked it out, it's worth the quick read: http://nodejs.org/docs/latest/api/modules.html#loading_from_...
This module loading algorithm is what opens the door for npm to install nested dependencies in recursive node_modules subdirectories.
I won't claim to know what the best alternative would look like, but I'd definitely take npm over PEAR any day.
Although package management can cause it's own problems like dependency hell or multiple packages that do the same thing but none of them do it well.
Actually, what I found sorely missing in php and started loving in the ruby world is bundler. It's not a package manager, but a dependency manager. You feed it a list of gems that you directly depend on and it figures out which gems to install in which versions so that all direct and indirect dependencies are satisfied. If it can't, it prints a meaningful error message. On top of that you can stack tools like gemnasium which track which of your dependencies were updated.
I do have a couple of projects that depend on about a hundred different gems. Managing that would be impossible without bundler. On the other hand, having a tool that enables you to manage this complexity makes you write smaller and smaller self-contained, separately testable gems that just add some little piece of functionality on top of some other lib or pulls together multiple libs and adds the glue code. It's actually common that even full-stack frameworks like rails or padrino consist of a handfull of separate pieces with another gem gluing them together. Even ORMs such as datamapper come in pieces.
I know of no tool in the php world that even attempts to solve this problem.
The PEAR maintainers seem to disagree with the direction PHP is going as a language, so they don't keep it up to date with changes in the language. If you want to use PEAR, you need to either hack the code yourself (why use PEAR) or you need to put PHP in an out-of-date compatibility mode.
existing php projects won't soon benefit from language features and new frameworks without significant rewrites, and their absence make php less attractive for the style of development he seems to favor.
Why not just use javascript?
"PHP needs a modern package manager"
Is Packagist (http://packagist.org/) going to fill this need?
If not, what is missing? Bigger community? Easier integration? Time?
PHP CMSes had package managers for years. It wouldn't hurt to look at them and learn what they did right and wrong before cloning Ruby/CPAN/NPM solutions.
I'm a micro-php sympathizer, but I'm wondering if the pendulum isn't swinging a little too far in the other direction here. Import libraries function by function? Are there really no libraries that are small and address your needs with a minimum of cruft? If we don't want to import a simple router class, maybe the solution is to trim down the class, not break it up into discrete functions to be imported one by one. What would a more-than-small application look like like this? I fear it'd look crazy; but I'm just speculating.
Anyway, if you really want to import functions it's not like it's impossible.
Then `require 'lib/myFunk.php';` I'm sure there are more graceful ways in other languages but this works. (EDIT: Namespaces notwithstanding ;)Now there's too much atrocious code out there that would break with updates to PHP. I firmly believe PHP.next has to declare it's going to break everything, take all that we've learned now, and build a great web language that is easy to use.
I think these changes are great and PEAR's future is looking a lot brighter due to the people driving these changes.
*Personally I think it's a good idea to have some kind of vetting process in place. If you look at for instance the WordPress plugin repository as an example of a repository without it you'll notice loads of crappy plugins or abandoned code. I presume that with a vetting process (and maintainer process) one could prevent this from happening.
Moving to Github is a good move. Opening up some sort of "PEAR commons" where the requirements aren't as arduous as PEAR proper would go a long way.
When package dependencies are tracked explicitly there's a very natural, Page-rank like effect that pushes the best, most reliable packages to the forefront because everyone depends on them. Just look at npm's "most depended on" list: http://search.npmjs.org/ You can look at any package and see what other packages depend on it.
PEAR's curation process feels a lot like Yahoo's of old's curated link database. npm's feels a lot like Google's "anyone can publish, we'll track dependencies, the good stuff will surface".
I do agree that along with package management there should be a strong community/social component involved that critiques & communicates about packages available.
You can write simple and concise OO code in PHP without writing Java-inspired superverbose code.
My answer was to use plain functions as helpers, at first because they could easily become Smarty modifiers, and later realized the function-only pattern worked really well across the whole app.
I write code like this...
# file: helpers/say_hello.php
Which is auto loaded by the framework and usable like this:(PHP):
(Smarty):It's not as "structured" as methods in a class that extends a Controller class, but it works just as well and eliminates a good bit of boilerplate code in the process. Also helps new developers get up to speed quickly I've found.
My one bit of criticism might be, in a plain php file without any code block wrapping handler logic, it's harder to understand context. I don't know exactly where this file is getting executed, and so it's not clear where the contextual properties are coming from? Perhaps that's the point.
Releasing the framework separately would take care not to add confusion to the documentation side of things. Then again, having a separate 'elefant-core' project that the CMS builds on may even help...