Related
As far as I understand, every enabled module in a ZF2 application is loaded for every request (unless one uses optimization methods such as that offered by the zf2-lazy-loading-module module). I've been keeping an eye on modules that get published on modules.zendframework.org and I've come across modules which offer extremely limited functionality, such as the AkrabatFormatUkTelephone module which purpose is to format phone numbers to UK format.
Whilst I understand development should focus on creating single purpose modules that are good at doing one thing (instead of modules which do many things but not in a very good way), I'm thinking if we start using modules which offer such limited functionality as the one mentioned, we will need to combine hundreds of modules in order to build a rich application which could be disastrous for performance. Instead I would expect this sort of functionality to be put in a class (e.g. Zend\I18n?) and loaded on demand which would be more optimized. But knowing Akrabat's reputation I'm thinking I must be missing something, hence my question:
Is the loading of modules such as the one I mentioned significantly worse for performance than loading the same functionality via PHP classes (or is it similar due to the way ZF2 has been designed)? Does anybody have any figures (i.e. is it 5%, 10%, 15% slower) about module vs class loading performance?
Don't take this comment as a final answer, as hopefully someone of the ZF2 devs will shed some more insight to it, but generally only Module.php and usually module.config.php will be actively loaded. Everything else will simply be registered and be called on demand. So as long as your Module.php and module.config.php are not TOO big in filesize, the performance shouldn't be THAT big of an issue
In the case of Akrabats example, all that's happening is, the registry of a new ViewHelper. Nothing else. The same with all other view helpers inside of Zend. Performance won't really matter a lot in these cases.
Personally the Skeleton loaded with 80ms on my Webspace and with BjyAuthorize, ZfcBase, ZfcUser and my own module, the loading time ramped up to 100ms. And this is without any sort of memory caching enabled!
Loading a module is not much more than loading any class, like Sam pointed out.
As long as you don't use anything from your module and do things right, it's just beeing registered.
Now what does "do things right" mean?
Just try to put a big nonsense loop inside your module classes bootstrap() method. You will see that this slows down every request on your application, because the bootstrap method of your module is called on every request and it should be used very carefully, only for light weight tasks. The purposes you usually use the bootstrap() method for, won't even slow down your app for a millisecond, but writing a file to the disk in this method could slow down your app for many seconds in each request.
If your app becomes really heavy, you should use the classmap_autoloader and some caching wherever you can. If you did "things right", you won't have any performance problems, just because you have many modules or many classes in your app. One could say, it's just all about algorithms.
Keep going on using best practices, like the one you mentioned. Usually these aren't the bottlenecks of your application, but your own algorithms and failures are.
edit:
When you're using modules from the community, you should always check them for performance issues. Even a module that seems to be very light could be a bottleneck for your application if it has bad algorithms. But the case that you're loading an additional module is not the point of it.
Good question. I would like to contribute a little bit to the reaction of Sam.
Module performance is not solely the loading of the module (which is, as pointed out quite fast), but also the communication of the modules in-between. So this question might boil down to: how slow/fast is the ServiceLocator and Event-driven system in comparison to traditional non-modulair systems?
I recall that ZF2 was build with performance in mind. For instance, the ServiceLocator registers factories, so that objects can be instantiated on-the-fly. So this requires only a few extra in-memory objects and instantiations, I guess this does not impact the total performance for your application much. The EventManager works in much the same way and I have not seen it being overloaded with registered events, even in large applications.
What might slow down, on the other hand, is the loading of the modules configuration. I figure that using a cache might solve this problem. I'm not sure but maybe Zend Optimizer might do this already.
So, in short, applications should scale pretty wel, provided that modules behave well, and do not over-register events or misuse the ServiceLocator.
From the MVC component's perspective there are no modules at all! There's one big configuration file - a result of merge of every module's configuration. Unless your modules don't have a onBootstrap method or don't do much, module loading is as fast as invoking new Module on every one of them, which is painless and memory inexpensive.
The configuration merge procedure, which I mentioned above, happens only in DEV mode which is enabled by default.
There are number of tricks also to speed up your ZF2 application, like:
Enable merged config cache
Use EdpSuperluminal module
Return the ViewModel objects from actions, not arrays
Explicitly set the template name on the ViewModel
Use template maps instead of template path stack alone
Route order in the config matters! Its a LIFO queue (last in-first out).
Make sure you don't load Console modules in HTTP context.
Let the Composer do the autoloading, not ZF2
... and more. There's a quite good talk by Gary Hockin on the ZF2 app performance.
Authorization modules will surely slow down your app. There are number of things going down under the hood: the identity of the user needs to be fetched (from the database?), user needs to be authenticated agains your rules. Surely you can speed things up by using memcached or such, but this requires to have some knowledge about the lifecycle of the ZF2 application, about the modules you use, etc.
Also there is Zend Framework 3 going to be released soon, some things will go faster, but don't expect much. A lot of overhead is a result of your lack of knowledge about ZF2 - no offense!
As our company starts using Zend Framework as the base framework for most of our projects, we want to share some common elements across all our projects. I talk about things like:
An implementation of a model (based on doctrine2)
RBAC for the model, including user, group, role models
A xml-based templating engine for ajax backend interfaces
(you name it) ...
Basically, all things to put "zend on rails" and get going. What is the best way to package these components? I see two possibilities:
As modules
We include the necessary functions as separate modules into the modules folder.
Pro:
We can set routes and execute code, which is good for many modules (imaginary example: a paypal module needs some kind of callback url. If our module can set it up on its own, no configuration from the "project developer" is needed).
We can provide real functionality (like the user administration) out of the box
We have a bootstrap to set up autoloading and doctrine etc.
Con:
Bad place? Interferes with the users project
A little harder to share between projects (git submodules instead of classpath)
In the library folder
We put it in the library folder and point the classpath to it.
Pro:
Clean solution
Sharing across projects
Con:
Bootstrap has to be explicitly called
No direct routing or actions - everything has to be proxied through the concrete project
So, how do you solve this? Where do you put your reusable, general purpose stuff in zf?
I think you should use both approaches.
When developing "library-like" code, as in kind of "infrastructure" classes and other things that are reusable (like ZF's own components, Doctrine 2's components etc.), you can put them into the library directory. (or its own entirely separate project)
When developing actual ZF modules (like an auth module for example), then format the code around the ZF module structure.
I think by using this kind of approach you get all the benfits you listed, and pretty much none of the cons :)
As one additional idea, if you develop your architecture parts as "services", you could even keep them running as their own web service endpoints.
I am looking for a (small) library that helps me cleanly implement a front controller for my pet project and dispatches requests to single controller classes. The front controller/dispatcher and controller classes need to be fully unittestable without sending HTTP requests.
Requirements
PSR-0 compatible
installable via its own PEAR channel
support for unit testing:
checking if the correct HTTP headers are sent
catches output to allow inspection in unit tests
perferably PHPUnit helper methods to help inspecting the output (for different output types, i.e. HTML, XML, JSON)
allows setting of incoming HTTP headers, GET and POST parameters and cookies without actually doing HTTP requests
needs to be usable standalone - without the db abstraction, templating and so that the fat frameworks all provide
Background
SemanticScuttle, the application that is bound to get proper "C" support, is an existing, working application. The library needs to blend in it and needs to work with the existing structure and classes. I won't rewrite it to match a framework's specific required directory layout.
The application already has unittests, but based on HTTP requests which make them slow. Also, the current old way of having several dozens of .php files in the www directory isn't the most managable solution, which is why proper controller classes need to be introduced. All in all, there will be about 20-30 controllers.
Previous experience
In general, I was pretty happy with Zend Framework for some previous projects but it has several drawbacks:
not pear-installable, so I cannot use it as dependency in my pear-installble applications
only available as one fat download, so I manually need to extract the required bits from it - for each single ZF update.
while unit test support exists for ZF controllers, it's lacking some advanced utility functionality like assertions for json, HTTP status code and content type checks.
While these points seem to be nit-picking, they are important for me. If I have to implement them myself, I do not need to use an external libary but write my own.
What I don't want
StackOverflow has a million "what's the best PHP framework" questions (1, 2, 3, 4, 5), but I'm not looking for those but for a specific library that helps with controllers. If it's part of a modular framework, fine.
I also know the PHP framework comparison website, but it doesn't help answer my question since my requirements are not listed there.
And I know that I can build this all on my own and invent another microframework. But why? There are so many of them already, and one just has to have all that I need.
Related questions
What's your 'no framework' PHP framework?
How do you convert a page-based PHP application to MVC?
Knowing Symfony2 well, I can assure you it's definitely possible to use it just for the "C" in MVC. The models and templates are completely free and are typically executed from the Controllers anyway, so if you don't call Doctrine or Twig specifically, you can do what you want.
As for functional testing, which is really what you're talking about in your article, what you want to look at is the WebTestCase class, which is well complemented by the LiipFunctionalTestBundle bundle for more advanced cases.
That allows for some things like this example of testing a contact form that sends an email, where the entire HTTP request is done in process, since the framework is written to allow multiple requests per process and has no global state, this works very well and does not require a http server to be running or anything. As you can see I do assertions on the HTTP status code of the response too, and was able to capture the email without sending it since in test configuration sending of emails is disabled in the standard distro of Symfony2.
That being said, you could also just use the Request and Response classes from Symfony2's HttpFoundation component. It should allow you to test your code, but IMO you wouldn't get as many nice features as you could if you'd use the entire framework. Of course that's just my biased opinion ;)
I would recommend downloading the Symfony 2 framework Routing component: https://github.com/symfony/Routing
Documentation is found here: http://symfony.com/doc/current/book/routing.html
Perhaps it does not satisfy all you requirements, but it's the closest.
If you are familiar with symfony (which I think you are) you should check out silex From their website this is what they say about it:
A microframework provides the guts for building simple single-file apps. Silex aims to be:
Concise: Silex exposes an intuitive
and concise API that is fun to use.
Extensible: Silex has an extension
system based around the Pimple micro
service-container that makes it even
easier to tie in third party
libraries.
Testable: Silex uses
Symfony2's HttpKernel which abstracts
request and response. This makes it
very easy to test apps and the
framework itself. It also respects
the HTTP specification and encourages
its proper use.
I'd add Net_URL_Mapper, it doesn't have the assertions though. Is that why you ruled it out?
Another pretty interesting thing is silex. It also comes with controller tests. I'd use that over Symfony2. But that's my personal preference.
Quite a understandable wishlist. I think we all hate it in testing when we run into dependencies that make testing to havoc. Tests should be simple and short, having many things to solve before and after running each test can be a burden.
From the description of your question it looks like that you pretty specifically know what you're looking for.
My first reaction would be that you use PHPUnit for this. It does not qualify all your requirements, but it's a base you can build on. It's highly expendable and flexible, however it does not support PSR-0 but has an autoloader of it's own so probably that does not weight that hard.
From the information you give in your question I'm not sure if the design of your testsuite(s) or the design of your application are hindering in writing and performing the tests you would love to.
I smell sort of probably both. If your application code is not easily testable, then there is not much a testing framework like PHPUnit can do about. So for example, if your controllers do not use a request object with an interface, it's not so easy to inject some request that was not triggered by the HTTP request, but by your tests. As HTTP is most often the entry-point into a webapplication, it pays to abstract here for tests. There exist some suggestions apart from specific frameworks: Fig/Http. However this is just a pointer.
Similar is this with the database scenario you give: If your application code is depending on the database, then your tests will be as well. If you don't want to test against your database all the time, you need to have your controllers being able to work w/o the concrete database. This is comparable with the HTTP requests.
There exists numerous approaches to cope with these circumstances, but as I read you question you don't look uneducated, but it's more you're looking for a better solution than exisiting ones.
As with every own code, it's pretty hard to find something that matches the own design. The best suggestion I can give is to extend PHPUnit to add those suites and constraints you need to for your application while you use the support of automated tests to refactor your application to fit the needs of how you would like to test.
So you can start with the tests and then develop the controller like you need it. This will keep your controller light I assume and help you to find the solutions you need.
If you find something that is missing with PHPUnit, you can first extend it on your own and additionally the author is very helpful in adding missing features.
Keep in mind that if there does not exist what you need, you need to code it your own. However if you're able to share (part) of the work with others, you most often get a benefit than by doing everything alone. That's a point for an existing framework, be it for testing or the application.
So if as of yet there is no such controller / MVC that does support easy unit-testing out of the box that fits your needs, chime in and develop one TDD-wise. If done right it can exactly match your requirements. However I think you're not alone with this problem. So not a very concrete answer, but I can only say that I made very good experiences with PHPUnit and it's extendability. That includes output tests you're mentioning in your question.
And probably a little differentiation at the end: It's one thing to test code-units and another to test if they all work in concert in the application with it's various requests. The last most often requires larger test setups by nature. However, if you can separate units from each other and clearly define with which other units they interact, then you normally only need to test the interaction between those which can reduce the setup. This does not save you from infrastructure problems, but those are normally not tested with unit-tests anyway (albeit you can extend PHPUnit to perform other type of checks).
A popular framework - even with a bad design - has the big plus that components tend to be better tested by use. That normally helps to go over the first years of your application until design issues in a framework make you need to rewrite your whole code base (probably).
As controllers often are sort in the middle of everything, this can lead to the scenario that you tend to test the whole application while you only want to test the controller(s). So you should think about the design and role of the controllers and their place within the overall application, what you really want to test with your controllers, so you can really make them testable according to your needs. If you don't need to test the database, you don't need to test the models. So you could mock a model returning random data to take it to the extreme. But if you want to test if HTTP handling is right, then probably a unit that abstracts HTTP handling is needed at first. Each controller relying on this would not be needed to test (theoretically) as the HTTP processing has been tested already. It's a question of the level of abstraction as well. There is no overall solution, it's only that frameworks can offer something but you're then bound to those paradigms the framework expects. AFAIK testing in php is getting more and more popular but that doesn't mean that the existing frameworks have good support for it. I know from the zend framework that they are working on this to improve the situation since longer. So it's probably worth to look into the more recent developments in the more popular frameworks to what this leads to as well.
And for the very specifics, you need to test on your own always.
Opting to PHPUnit and own testcases however does look as a practically way to me. Code your controllers as you need them for your project in TDD and you should get what you need.
Probably the more component based approach of Symfony 2 is better fitting your needs than what you experienced with Zend Framework. However, I can not suggest you anything specific as needs highly differ within application design. What's a quick and solid solution for one application is a burden for the other. See Page Controller.
You could take a look at the http://ezcomponents.org/ witch is becoming apache zeta
There are three ways how to make eZ components available for your PHP environment, please read the whole of this article before continuing with the practical part:
Use PEAR Installer for convenient installation via command line
Download eZ components packaged in an archive
Get the latest sources from SVN
I haven't got my hands into it yet but looks like a good solution...
Seldaek: WebTestCase isn't quite the right thing - it's for testing a view directly, and a controller or model only indirectly.
A unit test case for a controller would invoke the controller, likely giving it a mock object for the templating engine (e.g. a mock Smarty object), then check the values that were assigned to that object for display: for example, if you invoked the controller for /countries/south-sudan, you could check that the template variable $continent was set to "Africa". This kind of unit testing wouldn't actually involve any template rendering in most cases.
I know questions like this have been asked numerous times, but not quite this one. Forgive me if I overlooked an obvious duplicate.
In the core of many of my web applications is a self-written user/session management class that in its origins dates back to 2002.
I have decided that it is time for a fundamental re-write or, preferably, the introduction of a ready-made standard library.
My requirements for that library would be:
Object oriented, clean, excellent code
Full session management: Wrapper to session_start() and consorts
Would ideally provide various storage methods (PHP Standard /tmp, database based)
Would ideally be able to connect to different types of user data storage, but mySQL will do fine
Would ideally provide convenient functions for supporting OpenID, but that's a fancy thought, no requirement right now
Methods: Verify session, get user data, get session data, log in user, log out user
Settings: Session lifetime, password encryption
Must be Open Source
And if it's very generic, a user management API or a generic connector to the user management of the surrounding application would be nice:
Create/Update/delete user records
Fetch and modify data of currently logged in user
this is so basic, and so security relevant, that I would expect that there is a standard solution to this, however I don't know of any, and all the big CMSs and blogs seem to be rolling their own.
My two questions:
Do you know such a component as a generic, stand-alone library?
Could somebody with deep knowledge in Zend Framework tell me whether it is possible to use Zend_auth and/or Zend_session standalone, at the core of a big application that has otherwise nothing to do with ZF, without running in to trouble?
May I suggest the authentication library that I have written? It is a generic library (not written for or part of a framework): http://ulogin.sourceforge.net
Could somebody with deep knowledge in Zend Framework tell me whether it is possible to use Zend_auth and/or Zend_session standalone, at the core of a big application that has otherwise nothing to do with ZF, without running in to trouble?
I don't have deep knowledge of the Zend Framework, but I have used various components (e.g. Zend_Search) without creating a Zend_Application object or using the MVC framework and I am sure the rest of the library is also designed to be totally modular. Last time I dug though the Zend_Session code, I didn't find any includes outside Zend/Session/. A quick google seemed to confirm this for Zend_Auth, along with the Zend FAQ which states:
Is ZF a component library or a framework?
Simple answer: both. Zend Framework provides all the components required for most web applications in a single distribution. But Zend Framework components are also loosely coupled, making it easy to use just a few components in a web application- even alongside other frameworks! Using this use-at-will architecture, we are implementing features commonly found in more monolithic frameworks. In fact, we are currently working on a tooling component for the 1.8 release that will make it simpler to build applications using ZF components, yet will not sacrifice the use-at-will nature of existing ZF components. It's a testament to the use-at-will architecture of Zend Framework that the tooling component itself can be used standalone.
The only thing I had to do when not using Zend_Search with the MVC framework was add the directory where you installed the Zend Framework to the include path due to the includes in the Zend library. The documentation doesn't document the includes you need when not using the Zend Autoloader, but as everything uses the PEAR class naming scheme, it is easy to deduce from the class names you are using. (so the class Foo_Bar_File would require you to include Foo/Bar/File.php )
There are several OpenID libraries available.
http://wiki.openid.net/Libraries#php
For the rest you might as well roll your own, since figuring out someone else's library would probably be more trouble than it's worth.
My understanding is that there is no standard library because there is no standard definition of what a user is.
In some of my applications, users simply log in to do stuff. In others, users are part of a company and their permissions and data access are limited by the limits of that company and the subscription level paid for by the company. In other applications, some users are admins with access to everything, some users are admins with access to some data (row level), and other users are the clients of those admins, with access only to their own data. Some users are tied to firms/companies/customers, other users are not. Some users are just a username and password, others are a large object graph with clients, order histories, report preferences, comments, etc.
Maybe I'm wrong and there's some clean way of abstracting all of those requirements into a system that doesn't require five layers of subclassing and a thousand DB hits to log someone in. I haven't found it though.
Is there any open-source, PHP based, role-based access control system that can be used for CodeIgniter?
Maybe I'm misunderstanding the question, but isn't the whole point of Role-Based Access Control (RBAC) to avoid Access Control Lists (ACLs)?
RBAC differs from access control lists (ACLs) (...) in that it assigns permissions to specific operations with meaning in the organization, rather than to low-level data objects. For example, an access control list could be used to grant or deny write access to a particular system file, but it would not say in what ways that file could be changed. In an RBAC-based system, an operation might be to create a 'credit account' transaction in a financial application (...). The assignment of permission to perform a particular operation is meaningful because the operations are fine-grained and themselves have meaning within the application.
(Quote: Wikipedia)
I don't know the specifics on Zend_ACL or the other implementations mentioned, but if they are ACL-based, I would not recommend using them for role-based authorization.
Brandon Savage gave a presentation on his PHP package "ApplicationACL" that may or may not accomplish role-based access. PHPGACL might work as well, but I can't tell you for sure.
What I can tell you, however, is the Zend_ACL component of the Zend Framework will do role-based setups (however you'll have to subclass to check multiple roles at once). Granted the pain of this is you'll have to pull out Zend_ACL, I do not believe it has any external dependencies, from the monolithic download (or SVN checkout).
The nice thing about Zend_ACL is though its storage agnostic. You can either rebuild it every time or it's designed to be serialized (I use a combination of both, serialize for the cache and rebuild from the DB).
I created an Open Source project called PHP-Bouncer which may be of interest to you. It's still fairly young, but works well and is easy to configure. I ended up developing it because none of the existing solutions seemed to meet my needs. I hope this helps!
phpgacl http://phpgacl.sourceforge.net/ is a generic acl based access control framework
while I don't know about any CI specific implementation, i know that you only need the main class file to make phpgacl work. So i belive that integration with CI won't be any problem. (I've work passingly with CI)
Here are two RBAC libraries for PHP I found:
https://github.com/leighmacdonald/php_rbac
https://github.com/brandonlamb/php-rbac
I actually used the first one in PolyAuth: https://github.com/Polycademy/PolyAuth/
It's a full featured auth library that includes NIST level 1 RBAC. And yes, RBAC is not the same as an ACL. I use Codeigniter as well, all you have to do is use the PDO driver and pass in the connection id. See this tutorial for how to do that: http://codebyjeff.com/blog/2013/03/codeigniter-with-pdo
Found out about Khaos ACL which is a CI library... I'm also checking out phpgacl and how to use it for CI... Have'nt checked Zend ACL yet. But maybe it can be "ported" to CI
Try DX_Auth plugin for CodeIgniter. I am working on a similar (rather, superset) of the functions that DX_Auth have. My set of CI addon's include display of menus (that can be controlled via CSS), Role-bases access controll before controller is invoked and other features. I hope to publish it soon. Will give project URL when I do so
RBAC != ACL - Roland has the only correct answer for this question.
BTW of course it is an essential part of a framework to implement any kind of permission system - at least there is no point in using a framework, if it does not give you a well engeneered RBAC system - it might be better using a simple template system with any ORM layer then.
It is a common antipattern in the php world, that frameworks like Ruby or Django are "cloned" only as a subset of what these modern frameworks deliver - as a typical syndrome yuo see a lack of good ACL or RBAC integration into these frameworks - what essentially is a joke.
There is currently only the Yii PHP Framework that comes with a decent RBAC implementation.
I know the trail is cold, but a new project has popped up :
PHP-RBAC is a PHP Hierarchical NIST Level 2 Standard Role Based Access Control and is pretty mature. It is also an OWASP project.
I hope you enjoy it at http://phprbac.net
http://www.jframework.info (deadlink)
jFramework has a standard NIST level 2 RBAC with enhancements which is said to be the fastest available (includes benchmarks) it can operate on a single SQLite database file and is tested thoroughly, works like a glove.
Has a dependency on jFramework DBAL but you can simple replace DBAL SQL Queries in the code with your desired DBAL and of course you can use jFramework in a SOP manner.
Ion Auth Library uses users and groups - https://github.com/benedmunds/CodeIgniter-Ion-Auth
but there are no working RBAC system to use them and manage. But you can white your functions.