The introduction of list comprehensions is nice and should replace numerous functions. For example, I'm not sure why they're adding the array_column function into PHP 5.5 at the same time as list comprehensions as:
$names = array_column($users, 'name');
// is the same as
$names = [foreach ($users as $user) yield $user['name']];
The only possible reason would be due to a significant speed difference, but I'd suggest improving the efficiency of the list comprehension system (even if just for common cases) than adding more functions.
As opposed to the introduction of list comprehensions, I can't say I like the solution for parameter skipping though... I disagree with the author -- many optional arguments is not a problem, but only if keyword arguments or a similar style are used. Consider the example they give:
// This create query function in PHP
create_query("deleted=0", "name", default, default, false);
// could be represented like this with keyword arguments
create_query("deleted=0", "name", escape_arguments=false)
I tend to find keyword arguments serve the purpose of self documentation as well -- I still have no clue what the false flag would be for the PHP create_query statement.
Keyword arguments and many optional arguments can allow for beautiful and flexible functions, such as the Python Requests library[1].
r = requests.get('https://api.github.com/xyz')
# or we could add a few more complications
# -- no "defaults" in sight and also self documenting
r = requests.get('https://api.github.com/xyz',
auth=('user', 'pass'), timeout=0.5, allow_redirects=True)
One major disadvantage with so many functions is the cluttered global namespace[1]. PHP only added namespaces in 5.3.0 and can't modularize their globals into namespaces without causing massive backwards compatibility problems. PHP is stuck with a polluted global namespace, I'd be wary of adding more. Mind you, I'm well aware that this feeling could just be as I'm primarily a Python coder -- in PHP, you perform array_keys($xyz) whilst in Python it's xyz.keys(). Whilst you might consider Python as cheating by pushing all the functions onto the objects, it results in a far happier global namespace[2].
As far as list comprehensions, I tend to find list comprehensions the readable and self documenting, at least in Python where I most commonly see them. If nothing else, what is the ordering of the arguments for the equivalent non list comprehension? With list comprehensions you don't have that impedance.
// Python example with filter vs list comprehension
// Filter requires you to remember the ordering --
// and does it filter on True or False?
filter(lambda x: x % 2 == 0, range(10)) --> 0 2 4 6 8
// The list comprehension is self documenting
[x for x in range(10) if x % 2 == 0] --> 0 2 4 6 8
I can also convert the majority of list comprehensions into English quite easily -- "output x for each x in range(10) if x is divisible by 2" (though it may be cleaner if it was "for each x in range(10) [output x] if x is divisible by 2").
Yes what the code does is very clear, but the function call is even a level up clearer, maybe you don't want to know how it does it's job, you just want an array of values in a column (array_column(array, column)).
Personally I like comprehensions, but I tend to disguise them behind a function, it's much more clear to me. (but if I need the code to be super fast, I avoid using an extra function.)
>PHP only added namespaces in 5.3.0 and can't modularize their globals into namespaces without causing massive backwards compatibility problems. PHP is stuck with a polluted global namespace
They could do what Python did for 3.0, and make a tool similar to Python's 2to3 that replaces global namespace references.
That sounds like a disaster. I don't think anyone wants to follow Python's lead on breaking backwards compatibility without a very good reason. A much better reason than a cluttered namespace.
If they're going to allow queries on arrays of lists -- not a bad idea -- why not simply implement a SQL subset? I can see a huge collection of new array functions...
I agree with you on using keyword arguments, it makes it more obvious (and where there are many optional parameters, may save some typing!).
With regards to the array_column function, PHP has a history of providing such functions for common operations, even where the same functionality can be replicated with more generic code constructs. For me, the function example you provide is more readable than the comprehension example, requires less typing and provides less room for mistakes. I.E. its simpler in this case, and that’s part of the way PHP rolls. There is of course an argument that functions like this should be provided by external libraries or frameworks rather than in the core of the language, but that debate has been had many times and PHP has come down on the side of including them. This is one of the reasons developers like me like PHP. YMMV.
Agreed on keyword args. I maintain Requests for PHP [1] which has a very similar API to Python Requests, and at the moment, you have to use an array as the options parameter.
You can, but: some function already exist with existing APIs - especially in libraries and existing internal PHP functions - and currently there's no way to say "I want default for the second parameter, but non-default for the third", unless you copy-paste the default from the docs.
array_column looks like a half-assed version of map. Looks like PHP hasn't changed a bit. Functions that do half of what their supposed to do and have odd names that depart wildly from industry standard language.
That's not what he's referring to. He's specifically referring to a read-only that only affects external classes. So, the object itself could write to that field, but nothing else could.
I do not believe you can improve generic list comprehension/generator system to a level it would have the speed of a specialized C function, unless you make a special case in the compiler which would effectively call such function instead of actually generating the code as written.
I was confused by the password hashing example since it doesn't appear to use a salt (which was the main reason to implement it at all). Even more confusing, the RCF says it will auto generate a salt if none is passed.
The explanation, a bit further down in the eRFC is that the function password_hash doesn't actually return a password hash, but a string including the algorithm and options used, the salt and the hash itself.
From the RFC:
> It's important to note that the output of crypt() (and hence password_hash()) contains all the information that will be needed to verify the hash later. Therefore, if the default hashing algorithm changes, or the user changes their algorithm, old hashed passwords would still continue to function and will be validated properly.
> PHP 5.5 will no longer support Windows XP and 2003. Those systems are around a decade old, so PHP is pulling the plug on them.
Given the recent threads about planned obsolescence (Apple) and OS fragmentation (Android) I'm curious what is missing from XP/2003 that is part of Vista+. Are there still exciting things happening in the world of OS APIs that are relevant for server software?
Or does this just mean that noone will actively test the binaries on XP anymore?
The VS2010 MSVCRT still runs on Windows XP SP2+ as mentioned in your second link.
The VS2012 MSVCRT will not run on XP initially, but a post-RTM patch to bring XP support back was mentioned on the VS blog[1]. So that would only prevent XP support between the VS2012 release and the post-RTM patch, and only if the PHP team upgraded at the first chance.
I can foresee them making a turn on this decision and continuing to support XP until developers actually stop using XP anymore. XP isn't going away anytime soon.
It was nice to see short tags "<?" coming back in 5.4. Before that, they used to say, don't use short tags, it's dangerous, breaks things. But users resisted it, and every ISP kept it open. And now from PHP 5.4 short tag is ON, regardless of whether one setts it On or Off in php.ini.
These sound like useful improvements, especially the new getter/setter syntax and scalar type hinting.
However, what I'd really like to see in next PHP would be the Composer dependency manager bundled in, a bit like Node.js nowadays ships with NPM. This has really brought a new world of cross-project code sharing into PHP:
I think composer is a bit too young to introduce into the language. Perhaps it will prove out to be robust, but I'd wait a little while before introducing it to core...
As someone who has worked with him for quite some time, all I can say is so very much agree. He blows me away left and right with his knowledge, ability and maturity (especially when it comes to code decisions). He's more senior than most developers that I know...
Yes, indeed. I was blown away when I read his about page. So many people yap about their years of knowledge and that PHP has all these problems and can be fixed this way and that way, but when told to shut up and fork the language and do it. They say "I can't, because I don't know C', yet this 17 year old is doing just that.
I was involved with PHP internals when type hinting came up for 5.3, and helped steer that discussion in some way [1]. It was a truly awful experience - at the time, the internals community was a very negative and poisonousness place. Does anyone still involved know if that has been fixed?
Given that you're involved in this - why add "with cast"? I thought the whole point of the feature, in regards to classes and arrays, is to be absolutely strict about function arguments. Once you start down the path of "well, as long as it's sort of like that," then you might as well accept objects that have toString defined in place of strings. Having worked in a large PHP project for years and trying to get it to a point of letting new developers spin up pretty quickly (and use PHPStorm efficiently), STRICT type hinting is one of the best tools possible!
So I'm not involved in the current discussion, but I remember some stuff from the last discussion and in general.
To start, you can consider the problem of type checking of scalars in a language with implicit type coercions. You're supposed to be able to treat 0 and 0.0 the same. At the same time, if you have a type check that says "int", you kinda expect to get an int. So "with cast" does that.
I know a lot of people find that ugly, and that you want to strictly that you must receive an int, but that's just not how people use PHP, and it doesn't make sense in the context of the language. As an example, you want to be able to add type checks to all the functions in the standard library, many of whom treat null, "0", 0 and 0.0 to be the same.
For PHP specifically, there is the additional consideration that PHP is supposed to be a newbie friendly language. There was a perception in the PHP internals community that newbie developers could not wrap their head around the concept of "types". I've heard people say that a developer shouldn't be required to think about what types his variable might hold. Clearly this is lunacy for many reasons, but there it is.
I just read the RFC, and I think it's very good. The only minor quibbles I have would be using the "compiler" instead of the parser to produce the hint, and whether or not you should cast if losing precision. But these are minor issues that should probably be ignored, since this improves the status quo considerably.
Could you elaborate how this poisonousness was manifesting itself? It would be interesting to know what exactly you think needed fixing. I know some people on the internals can be a bit abrasive from time to time, but nothing different from what happens on other technical lists (actually, far less rudeness that I've encountered in many other places). However, your experience seems to be significantly different, could you elaborate on that?
It's been a few years (2008-2009ish), so my memory has faded a little bit. I recall a lot of discussions where no-one would listen to other people (if I recall, the scalar type checking thread from PHP 5.3 was a good example). A lot of hostility to people trying to change or improve things. Quite a lot of hostility towards users or people who complained about PHP (check out the bug tracker - very aggressive). Oh, and a complete disregard for other members of the community by the people in charge-ish.
I know that there are a lot of discussions - sometimes very long and tiresome - but what you mean by "no one would listen to other people"? I.e. what would happened if things went differently and somebody would listen, say in the thread about 5.3 scalar type checking?
I regularly check the bug tracker and I haven't noticed any special aggressiveness - of course, some of the volunteers may sometime be impatient, especially with newbies, or trolls, some of which lately for some reason decided it is appropriate to publish their "php sucks" diatribes on the bugtracker - but I didn't notice any systematic aggressiveness. Some data would be helpful here - demonstrating the problem may be necessary for fixing it.
Same for regard for other members of the community. Various members of the community regularly participate in the discussions, and once PHP moved to git they also submit pulls, rfc, etc. Yet still you describe the situation as "complete disregard" - so what you would say should be happening instead?
When I say "no one would listen" I mean the long and tiresome discussions. I saw people just repeating themselves, without taking on board what other people were saying. I never saw these discussions end well. There was no consensus - the discussions eventually died out without any progress.
I think there might be some Stockholm Syndrome there. The volunteers in the PHP bug tracker are dicks! Or were, it's been 3 years so things may have changed. And I'm not talking about responses to trolls, I mean to ordinary users.
I mean they disregard the feelings of the other people in the community, not their code. I'm not really talking about how dysfunctional the coding practices were, I mean the actual community dynamics. It felt a lot like trolls feeding trolls.
There indeed was no consensus on the topic of strict typing and on some other topics - but it's only natural, people have different opinions and sometimes there's just no agreement between them. Especially if you are advocating wide regard for all people in the community, you have to accept that sometimes there would be no way to reach a decision that is agreeable to everyone. In the strict typing case that is what happened, there was no approach that was satisfactory to all, so the decision was to remain with the status quo. I don't think this makes PHP internals somehow hostile or "poisonous" - disagreement is a natural part of the process in such a diverse community, and in case there's no agreement on a new feature the natural way is to remain with the status quo.
My point is not that there should be consensus. My point is how the discussion went (and many similar discussions, not just one). Poison comes from how community members treat each other, not whether or not they can agree on something.
I've spent major time in 3 open source projects, gcc, Mozilla and PHP. All of them suffered from similar disagreement, from old code, from old decisions they need to move away from. The difference was that Mozilla and gcc manage to do it without being poisonous.
Unfortunately, I'm still not sure what you mean by "poisonous". To me it sounds like "community is poisonous because discussions are held wrong, and the discussions are wrong because community is poisonous". Maybe it's just me but I have hard time understanding what exactly is the problem here except for the fact that you obviously dislike something about PHP community. But if somebody asked me what exactly you dislike and what you'd have fixed if you could - I couldn't really give any meaningful answer.
To be honest, I think you are trying really hard to pretend my points aren't made rather than trying to use my points to investigate the phenomenon. I'll admit I'm not explaining them terribly well - its been 4 years since I've taken active part - but there's enough information in there that you could use it as a starting point if you were truly interested, which I think you aren't.
Sorry, your assumption about my motives is wrong. I would be really interested in finding out what exactly people on internals did so you call PHP dev community "poisonous" on every available opportunity (this is not the first time I read this from you, though it is the first time I had a chance to try and find out why). Unfortunately, I was unable to understand what offended you so much. If you didn't guess it yet, I was present on the internals list at that time (and long before and after that) so I had the opportunity to personally observe all those tiresome and long discussions and many more. So I thought I have pretty good starting point and enough information to at least try to understand your complaints. However, I still failed to figure out why you think PHP dev community is "poisonous". I guess it's not to be, well, at least I tried.
I didn't assume anything about your motives, but I didn't mean to be harsh. You do come across as an "apologist" for the community though. There are of course many communities that behave similiarly, but that doesn't make them healthy.
Look at it this way - imagine you had a conversation with a group of people 4 years ago, and they acted like dicks. Now, four years later someone challenges you to explain how they were dicks. It's really hard to give an answer better than "i dont know, they were just dicks alright" :(
Pretty exciting, though empty() should be deprecated, not improved upon.
The bit about getting the fully qualified class name is important, but it still prevents you from doing something like:
function builder_factory( $var ) {
$class = $some_array[ $var ];
return new $class();
}
So you have to write a ton of boilerplate for something that used to be easy without namespaces, or write namespace traversal into your PHP (which isn't THAT hard, but is very ugly).
Parameter skipping looks intuitive and useful. Very important as we incorporate more functional paradigms into the code.
I don't believe scalar type hinting will make it in. There's just too much discussion around it. IMHO, it should be super strict. "1" is not an integer.
Getters and setters: meh. I guess it's good. Better than what we have now.
I don't believe PHP will do generators or list comprehensions right, so I'm not holding my breath on those.
I could see it being depreciated for use on non-arrays, but at the moment the only other method of detecting an empty array is `!count($arr)`, which is significantly slower if the array isn't empty.
Ultimately this isn't a language issue, it's a training issue. If you're using empty in place of isset, you're doing it wrong, the both serve completely different purposes.
What you mean "unreliable"? It is completely reliable and described in the documentation. It doesn't fit some use cases, in these cases you could use other facilities provided by the language, PHP can not have separate language construct for every use case.
That way $a == 5, $b == "10", $c == "10", and $d == "3". Much better and cleaner syntax in my opinion and a lot of other languages support something similar.
What people end up doing in practice is passing in arrays with key/value pairs. The => syntax would be the closest thing to the current way of doing things, except you'd get default values and type hinting. I'm all for it!
I'm still looking for a good way to combine array parameters with defaults and hinting in PHP 5.3. I've had some success using DTO's for primary API's:
function foo(SomeDTO $data) { ... }
foo(new SomeDTO(array("a" => "foo", "b" => 10)));
class SomeDTO extends BaseDTO {
/** @var string
@maxlength 10 */
public var $a;
/** @var int */
public var $b = 20;
}
The BaseDTO class uses reflection to parse the doc comments and figure out how to validate and set its input. It's the same idea as validation annotations in java. It works, but it's quite a heavy syntax, and I wish I had a lighter-weight alternative. I like PHP's loose typing inside an API's class, but when interfacing between API's I want strict typing.
Maybe I am missing something but never seen that in practice (the 'foo(1, $c=20)' bit), that's a really odd way to initialize a variable. Wouldn't mind if they change it, so that it breaks (with a warning or error). Or have you seen this syntax a lot?
Personally I’m not particular fond of this proposal.
In my eyes code that needs this feature is just badly
designed. Functions shouldn’t have 12 optional parameters.
I'm not fond of this proposal either, for it doesn't solve a problem named parameters do, which is that sometimes function parameters don't have a logical order, and cramming them into an array feel sloppy as hell.
I agree, named parameters are useful as well, but there's no reason that both shouldn't be implemented.
The problem with PHP is that, due to the nature of the interpreter, so many of these things are written as syntactical sugar which means that their implementations usually leave much to be desired.
> Very important as we incorporate more functional paradigms into the code.
There's nothing functional to skipping parameters, as far as I know. None of the functional languages I've used supports such a concept, nor would it make sense in most of them.
This is just a "would be nice" sort of post right? The main feature I'd want (list comprehensions) seems to be just a single programmer's guess at an upcoming feature with no real evidence.
Pay close attention to the "status" listed under each header. Some of these features have already landed in master, and others are still in various states of proposal. The author links to the official RFC for most of the proposed features.
I'm not sure if the list comprehensions feature has made it past the mailing list though.
Consistency in dereferencing is very important.
empty() should at some point be deprecated, but fixing this erratic behavior for now is good imo.
The default value for method arguments is a shockingly bad idea for a new feature, it only supports the old, bashed upon, code quality that have been PHPs greatest legacy problem.
If anything in this alley I'd like to see named arguments somehow.
I'm not so sure about property getter/setters as I find the syntax a bit awkward, all while magic methods lets you create getter/setter based APIs.
Like the article said, you can't use it with function calls because empty() itself is a construct of the language and not a function. So, empty(someFunc()) is an error. You'd have to put the return value of someFunc() in a variable and test it for emptiness, or do something like if (0 == strlen(someFunc())) { /* .. */ } which is overly verbose and not fast.
I think a standard password hash API is a good thing (there was a proposal for such a thing for Python recently on -ideas, though it was essentially rejected in favor of recommending/using passlib), but I'm wary of having default cost factors, that seems unwise: what are the defaults, how are they decided to be ok, and more importantly in what context are they updated over time (and based on what data)?
> The problem with it in it's current form is it does not allow for an application pepper.
Considering:
* no password hash algorithm I know of supports peppers
* that the API allows providing a custom salt
I don't see any issue with the API. If the cryptographic worth of peppers is ever demonstrated and a password hash is built to use peppers, the pepper can be provided as an option to that hash algorithm as the salt and cost already are in the proposed API.
Every hashing algorithm allows it, even bcrypt. Very simple example;
md5($salt.$pepper.$clearText);
The problem with this API is that if you pass in the "salt" as $salt.$pepper then the output hash also contains the pepper.
The whole point of a pepper is to keep a second salt out of the database. The user salt would be in the database, but the pepper should only be in the application code.
If your database is stolen, but your application code is safe the pepper increases the complexity of brute forcing, as they need to work out what the pepper is
The most common pepper algorithm I've seen is doing e.g. "bcrypt(hmac_sha512(password, pepper), salt)" instead of "bcrypt(password, salt)". This has a number of advantages over working the pepper into the hash itself:
1) this wrapper can be applied to any hash scheme, regardless of it's internal structure or options.
2) it doesn't expose the pepper within the hash string.
3) brute-forcing the hash w/o the pepper means you're searching for the 64-byte binary string returned by hmac_sha512. whereas (assuming all inputs are ASCII) "md5(salt+pepper+password)" can still be brute-forced, just treat the pepper as part of the password you're looking for.
That is not the meaning I intended in my usage of the word "support", but if you equate "support" and "is compatible with", then this API also "supports" peppers, just as much as bcrypt does.
> md5($salt.$pepper.$clearText)
How cute, not just md5 but length-extension vulnerable MD5. I'd recommend not using that scheme for MACs (and more generally not using md5 directly, really, as there are precious few reasons to do so)
> The problem with this API is that if you pass in the "salt" as $salt.$pepper then the output hash also contains the pepper.
Which just happens to be the exact same way bcrypt's API works. Here's an idea: combine the pepper to the password (this is usually done through hmac), not the salt. That's how you use a pepper and remain compatible with the Modular Crypt Format.
> The whole point of a pepper is to keep a second salt out of the database [blah blah blah]
Contrary to your apparent belief, I am aware of what peppers are, how they are used and what they're supposed to do.
That is not entirely true: the pepper is usually randomly generated, so a "smart" brute-forcing tool (using combinations and substitutions on a base corpus) will have a much harder time matching something.
Regarding the "constant dereferencing" proposal, how do you even make a language parser that can't apply array operations to literals in the first place? I'm trying very hard not to bash on PHP here, and this is a completely honest question. I can't figure out how you'd even go about breaking that if you wanted to. Anyone know the background there?
As I understand, it goes like this: in PHP grammar, expressions are divided into two classes: variables, and expressions without variables. To simplify, you can think variables start with $, expressions without variables don't. These two classes are handled in completely different ways. Since array literals are expressions without variables, it isn't too strange that $x[0] parses, but [0][0] doesn't.
One reason it is like that has to do with string interpolation. PHP interpolates $x[0] inside double quotes, but does not (and probably should not) interpolate [0][0]. I am not saying this is a good solution, but hopefully that answers "how is that even possible?" question.
This would probably ban "4[5]" but not "$x = 4; $x[5]".
PHP enforces a lot of things in the parser (as opposed to making bytecode and having a simple type checker). Instead of having a general "expression" type which can be dereferenced, they have different rules for scalars, strings, variables, function calls, etc. For a long time, you couldn't dereference the result of a function call, because the parser didn't allow it, so this is probably the same.
Enforcing it in the parser seems so horribly wrong. If you want to disallow stuff like 4[5] at compile time then you should do that in a separate pass on the AST, not in the parser itself. That's ought to be a semantic error, not a syntax error. Treating that separately would require all manner of special cases. But, I guess that must be what they do.
Yeah, there's tons of special cases in the parser. I worked on phc (http://phpcompiler.org), so I've read the PHP parser and helped write some of our own. We took the AST approach and it worked out pretty well. But PHP was written before its authors knew good interpreter design, and its currently very hard to refactor it out to a better design.
The proposals look great! But I'm missing one thing: Less fatal errors, or a better way to catch them. Especially for the case of calling a method on a null value. E.g.
$foo->getBar()->getBaz()
If getBar() return NULL for some reason, you get a fatal error which you cannot catch and handle without reverting to uglu hacks with a shutdown function.
My personal preference would be to have that statement return NULL and raise a warning or notice, alike to using uninitialized variables.
Don't return null from that function. Return NullObject which has __call() { return $this; } - then you could chain as many such calls as you want and they'd be OK with nulls. Then you could check for NullObject as easily as you could check for null - if($result instanceof NullObject) etc.
If there is scalar type hinting I wonder if that will lead to real method overloading by adding methods with different signatures or if devs will have to stick with the __call magic method, which I despise.
As far as I am aware, it is under consideration for Zend Engine 3 / PHP6. But certainly not for 5.5, and probably not in the 5.x series at all. Though how many 5.x releases are left is anyone’s guess, personally my crystal ball tells me we will get 5.6 followed by 6. My crystal ball also says we will all have flying cars by now.
I don't know what you're responding to, but viewing your comment in isolation, I disagree. I work for a large hospital that has standardized on XP as the OS for desktop machines, and most of our server VMs are running Windows Server 2003. (Can't comment on what OS is hosting the VMs.) I don't have the freedom to upgrade my PC or the servers I deploy my code on, but that doesn't mean I should be stuck with an old version of PHP.
No, I don't have a dire need. But almost no one has a dire need.
No matter how much PHP is improved upon, until there is a serious contender framework for it like Rails or Django, PHP will continue its route to extinction. Dinosaurs were once big and powerful. They dominated the landscape. They don't exist anymore.
No matter how much PHP is improved upon, until there is a serious contender framework for it like Rails or Django, PHP will continue its route to extinction.
I'm not sure if you're serious, but there are plenty of frameworks on a par with Rails at least (nb: I have zero experience with Django).
And finally, my favourite, Kohana. Absolutely infuriating since they essentially stopped writing documentation for new versions, but if I need to get something written quickly and reliably, this is my go-to call:
There are tonnes of "serious" frameworks for PHP (I've certainly missed out a few), and frankly, if you're going to try to attack PHP, this is the wrong angle from which to do so.
Please don't recommend CodeIgniter. I'm not normally one for swathing "x is bad" judgements, but CI is simply not in the same league as the other frameworks you mentioned.
Tell us why! With the low memory overhead, built-in cache, Active Record (+PDO support) and easy-to-understand MVC approach, I think it is the best framework for writing small to medium-sized web applications.
CI is not Zend, but nothing prevents you from using the Zend libraries with a small CI Library wrapper - I have done so many times in the past, and it works great.
CI gives you very little, and what it gives you is mostly categorically broken. The total lack of post-redirect-get and insane choices on the session data front meant I was using a custom session storage library I wrote instead of the bundled one.
We had issues where the router and loader were not playing nicely at all - we were using the 404 override option in order to do some custom routing (as the router was not flexible enough for even a very basic CMS). However because of how messy the routing code is, and how much of a hack the 404 override was (last time I checked there were several open bugs regarding this on their tracker, some over a year old and completely untouched), it completely blitzed the loaded libraries, so we had to add in more hacks to dodgily clear the cache of loaded libraries and re-run the loader in order to have them available. The only other way to do this would have been to modify the core loader to fix the bug there (but we didn't want to modify core code to make it easier to keep up to date with framework changes), or completely rewrite the router (which really needs to be done, it's a mess).
The database abstraction code is very kludgy and basically useless for anything beyond utterly, utterly basic use cases (there's a reason it's low overhead - it's low everything, including functionality!)
That's just a few of the things we ran into. By the time we went to production I estimate that out of the maybe 30% of CodeIgniter we were actually using for our project, I had re-implemented as custom libraries maybe a third of that amount just to get some sane behaviour, and work around long-standing bugs. Overall I got the feeling that the framework had no solid direction, some of the core components (most critically the loader and router) were quite obviously piles of hacks rather than having been designed and engineered, and honestly the framework was not really much more re-usable or robust than our own custom in-house one. I know it's a very common developer hubris to think you could write your own framework and do a better job, but in the case of CodeIgniter I can confidently make that claim.
On the more technical and abstract side, it's insane that it doesn't use standard PSR loading (so any other library you want to use you have to write a custom wrapper), and the guidance on making re-usable libraries / modules / packages (I can't even remember the right terminology, they use these words in strange ways) is... unclear at best. It uses globals, it's tightly coupled, everything a decent framework should categorically not be. Overall I would say that the level of technical ability on people using and contributing to CI is very low, and most people I've spoken to that think it's great haven't actually used any other framework (which is, frankly, endemic of a large portion of the PHP-using world)
Edit: Also if you care about overhead, you're not writing what I would call a small to medium sized application! Any framework out there worth its salt (and many that are not) will be able to run your application just fine, it's extremely unlikely that the PHP layer will be the bottleneck unless you're writing really terrible code or using a really terrible framework.
Please don't recommend CodeIgniter. I'm not normally one for swathing "x is bad" judgements, but CI is simply not in the same league as the other frameworks you mentioned.
I wouldn't have a few years ago, but the current version seems decent enough. Out of interest, what're your main complaints with it?
I'm not a huge fan of CI, but would prefer it to my personal bugbear, CakePHP.
Having taken over a project that uses CI at it's core, I've found a number of things that definitely put it in a league below frameworks that were built with PHP 5.3 in mind.
* Way too much magic - everything (libraries, models, etc.) is globbed onto a superglobal class, which breaks auto-complete in IDEs and in general makes debugging harder
* No proper autoloader (PSR-0 style) - the built in autoloader can't autoload anything that doesn't fit into the CI world which tends to lead to unnecessarily large classes (anything that isn't a model gets lumped into a library)
* Setting up routes gets messy fast (it's all defined as a single associative array)
* No built in template system (which, in my experience, encourages bad behavior in views)
Okay, so a bunch of personal preferences that don't actually matter in the real world? Thanks for your insight, but it does not make CodeIgniter bad.
> frameworks that were built with PHP 5.3 in mind.
Well no crap, CodeIgniter is built for newbies in mind, people who don't have up to date PHP installs because their shared hosting doesn't keep it THAT up to date.
The newest versions of CodeIgniter are VERY good, and just like the haters of PHP, you're just hating on versions of CodeIgniter that are at least 3 versions old. Learn the updated system, then base your claims on that, not something you looked at 2+ years ago.
Those aren't (all) personal preferences. Using superglobals is definitively bad, in the same way that using GOTO is. Not using PSR-0 autoloading is flying in the face of the community consensus and makes it much harder to use other libraries with CI compared to other frameworks.
Your point about PHP versions isn't very valid. 5.3 is over 3 years old now! Plenty of cheap hosts are far more up to date than that.
There is a difference between being "newbie friendly" (which I will admit, CI is - it's a lot easier to get into than say, Zend, by orders of magnitude) and "enabling bad practices". You could say that using mysqli and concatenating data into your queries is newbie friendly, and it is - it's a lot simpler conceptually than prepared statements, but that doesn't stop it being categorically a bad idea.
For the record my CI experience ended about 9 months ago, and I have contributed code to CI, so I feel that when I say certain parts of the internals are very badly coded I do have some valid perspective on that issue.
There's also Slim:
http://www.slimframework.com/
...which you could equate to something like Python's Flask (I think... I only have limited experience with Flask).
We used Slim to build a RESTful API for our product. It was a great experience. Really lightweight, yet the perfect amount of structure to make an easily extensible API.
I've been using Cake since around 1.1 and it started with a decent base but was not very consistent. I just recently upgraded to 2.2 and I was extremely surprised with the amount of refactor and polish in order to make it a very consistent and powerful framework. It's really top notch nowadays. The performance is also better (used to have to do some "hacks" to get good performance before) but I'm not sure how it compares to others.
To be fair, the biggest problem I have with Cake is its ORM; it just feels unnatural to me. You ask for some data, and get back an associative array of values, which you can't do anything with but pass elsewhere. It just lacks a certain sense of OOPiness for me :)
I feel the same way, and I've been trying to get away from Cake for a while, but the fact that everything except the quirkiness of the ORM is so nice that I stick with it.
Also, the next version is supposed to redo the ORM to return actual models.
I wonder if the performance will be better or worst though. Creating tons of objects might impact it but they might be able to do more lazy loading to help.
I've found that Laravel is quite a bit nicer than most other frameworks in PHP. It uses some stuff from Symfony as well. I don't think it's contending with Django quite yet, but it's extremely nice to use and work with. I honestly don't feel like I'm writing PHP when using it.
The beauty of PHP is that it is simple to learn and easy to setup. That is why it is popular and will continue to be. Additions, such as the easy-to-use password encryption, are brilliant because it will make it even easier to move from adding some dynamic functionality to building a full app.
Disclaimer: I am working for a shop with much PHP knowledge. There are some really nice frameworks for PHP - for example we are using Yii (http://www.yiiframework.com/), Symfony (http://www.symfony-project.org/) and Flow3 (http://flow3.typo3.org/). I was using Yii in one of my projects and it worked really nice (altough I can't compare it to Rails or Django, because I have no experience with those).
Can you tell us more about your experiences with FLOW3? I work a TYPO3-shop, but hadn't had the chance to use neither ExtBase or FLOW3 much, but it looks exciting, at least after some superficial glances.
Dinosaurs dominated the ecosystem for 135 millions of years out of last 200, and it took a major extinction event - most probably of extra-terrestial origin - which wiped about half of the existing species off the face of the planet to do them away.
I think you meant the comparison as insulting, but it actually isn't. You're saying PHP is a T-Rex of web development. It's a nice compliment :)
PHP frameworks are pretty decent, and widely liked (if not loved). Though for some reason this doesn't apply to PHP applications: plenty of people dislike Drupal, or WordPress, or Magento. I'm not sure if there's an equivalent situation across languages--does Ruby or Python have loved frameworks and libraries, but unloved (though widely-used) applications?
Wordpress (as stated earlier) is a gong show. I do think people use Wordpress in far too many use cases where other solutions would work better. If you're a designer type with limited code knowledge, or an IT goon who can't really code but can script, Wordpress is often a good fit. But any experienced software developer is going to take one look at the internals and immediately close the editor. I do hear it's getting better, but it's been a while since I last looked at it.
Drupal is an odd duck - it's a framework with a built in CMS. It's immensely powerful for many developers who put the time in to learn it, but the experience is often jarring for traditional "object oriented" developers so they come away with a bad taste in their mouth: "no objects? this is icky!"
Of all the major PHP projects, Drupal seems to be the one embracing good software architecture - Drupal 8 looks to be amazing. It's come a long way from the days of Drupal 5.
Drupal 8 looks very promising with its adoption of Symfony Elements (HttpFoundation, HttpKernel, Routing, ClassLoader, EventDispatcher, DependencyInjection). Presumably it will be easy to integrate with other Symfony stuff and Symfony itself will benefit from the huge Drupal community.
Plenty of people dislike Drupal, or WordPress, or Magento
I can't speak for Drupal or Magento, but WordPress's codebase is a world of pain. I've written a few plugins in the past, and the WordPress code is simply hell to work with.
Drupal is ok, but a bit old-fashioned and quirky. It's highly callback/hook based, which is fine, but it doesn't always have hooks where you need them, in which case it gets pretty ugly.
Magento is on a whole other level of suck. I worked on a highly customized Magento site 3 years ago, and it was the worst experience of my professional career - lousy software and client-from-hades.
The Magento folder structure is just completely insane...some of the templates are like 8 or 9 subfolders deep, and it's the huge mashed up pile of Zend Framework and homegrown MVC, none of which is well documented (Since after all, they want to push you to paid support...)
Oh, and to further cement the suck, the main database tables are in EAV form. Tons of fun to be had.
billpatrianakos: FYI, it appears you've been hellbanned, presumably from the last PHP megathread (judging by your comment history and when they started going dead). Might want to contact pg about it.
As opposed to the introduction of list comprehensions, I can't say I like the solution for parameter skipping though... I disagree with the author -- many optional arguments is not a problem, but only if keyword arguments or a similar style are used. Consider the example they give:
I tend to find keyword arguments serve the purpose of self documentation as well -- I still have no clue what the false flag would be for the PHP create_query statement.Keyword arguments and many optional arguments can allow for beautiful and flexible functions, such as the Python Requests library[1].
[1]: http://docs.python-requests.org/