Is the whole Zend Framework stack rebuilt for each request? - php

I am working on a web application built with php and zend framework 2. I come from a Java EE background. It seems to me that for each http request the whole zend application stack is being rebuilt, reading a load of config files from disk, constructing all my services and whatnot. Is this correct? If so this seems rather strange and inefficient to me compared to the Java EE approach of having a load of application services that are initialized on web server start up and then have a lifetime across many requests. Seeing as the browser is making lots of little Ajax requests isn't this php/zend approach horribly slow? Do I need a paradigm shift in the way I approach web application design?

ZF2 can use caching to improve performance , the configuration also
can be cached as well .
any service or class in ZF2 shouldn't be constructed on every request , for example a db connection (ZF2 won't try to connect to db unless you are really doing something to the db server)
another example :
suppose you had an REST API , you need to use on one controller only , no need to construct this api on every request , you alternatively ask you module's service manager to construct that object for you on that controller only .
take a look at this blog , it might help you : http://www.masterzendframework.com/articles-2/zend-framework-2-core-concepts-understanding-dependency-injection
or http://akrabat.com/ or the ZF2 Team leader : Matthew Weier O'Phinney http://mwop.net/
(if I understand your question, sorry if not)

it's correct that php is not running in an environment, like java does.
This means that your php application is beeing initialized on each request.
It seems to me that for each http request the whole zend application stack is being rebuilt
But this is not correct. The initialization of your php- / zf2- application is not that heavy as you may think, when you're coming from java.
Don't think of something like a tomcat server being rebooted on each request. The whole Zend Framework is also not beeing loaded and your application classes aren't as well.
Only the classes that are needed for your specific request are being loaded.
PHP Frameworks make use of Autoloaders for this, so if you call new MyClass() in your app, that class will be loaded. And even the file containing "MyClass" is not being loaded from disc in many cases, but from ram-memory or bytecode cache.
If your server is set up correctly, the zf2 skeleton application for example will be loaded in a few milliseconds.
What about your services that need to be ready for your application?
They're nothing more than a "key" in an associative array, inside your configuration. When your application needs a service for your specific request, it will find the entry in your configuration array extremely fast. The Service will be initialized from a factory method or a factory class only for this request, but only the specific one which is needed.
Facebook is using php as well. It doesn't need a minute for each request right? If php worked the way you're thinking of it at the moment, it would take minutes or hours I guess - or just end up in a timeout :)

Related

Can you use xdebug to debug a microservice type architecture?

The code base I'm currently working with is one of the most difficult that I have ever worked with. I'm guessing it's based on a microservice type architecture, but badly executed. It consists of a main service and then makes calls via cURL to different separate services and uses the result of those calls. It's very complicated.
I know how to use xdebug to debug monolithic code but xdebug tends to follow the rabbit down the hole and hits the wall when it comes to a cURL call to a service.
Is there any way to "jump the gap" so to speak by intercepting the cURL call and starting xdebug on the service being called and having xdebug do the call, debug that service and then come back to the main service with the results?

Caching most of Symfony components and services

Having a Java background, one point I have missed during many years is that PHP recreates everything at every request.
So using the Symfony framework, we recreate every components of this - yet great - framework. Every service, all the router, are built and rebuilt.
We can cache data in $_SESSION, but we save 50 times data if we have 50 users. I thought I could use static or $_SERVER, but it doesn't work the Java way.
The PHP way is to use Memcached and there are plenty of exemples caching the doctrine requests, but I haven't seen any of them caching the Router or the Services. Do you know exemples, or is it just a bad idea ?
That's one of the characteristics of PHP, nothing lives once the request is finished.
There're a couple of projects where they wrap the bootstrapping process of symfony so it's only run once. Here's the project: php-pm and an article describing it's usage

ZF2 architecture. modules or separate projects for api, admin, client ect

I am developing project witch has console logic, restfull API, admin and client websites.
I have started building all of them in single ZF2 application. I am using Application module for client website and console logic, API module for API and Admin module for admin website. And then I have started writing unit tests I realized that then I am calling some part of my code every module is being loaded (for example when I am calling console script witch only works with emails via IMAP my api documentation tool swagger is printing warnings about no server name).
I think this should decrease app performance and changing one part can break another. And also all parts are really diferent(Console, Restfull, and html output. different plugins, vendors ect.).
And now I think how can I solve this problem. I would like to keep the structure:http://mysite/api for API, http://mysite/admin for admin, http://mysite/ for client site and php index.php action for console scripts.
How I should solve this problem? Should I split all those parts to separate ZF2 applications, or should I use same project but, some different autoloader. Or maybe there is some other good practices?
Don't rearchitect your whole application to fix a performance problem you think might exist. The module bootstrap overhead for ZF2 is quite low. If your modules really have no dependencies on each other at all, try benchmarking your application as a baseline, then try disabling one module to see what difference it makes. If it doesn't make much difference, I'd keep it as it is.

PHP front controller library with support for unit testing

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.

Zend Framework app as a web service

I'm developing a zend framework app that's just going to act as a web service. I have no need to ever output HTML at any point in the application and don't even want the overhead of creating empty view files.
I want my app to output XML by default, JSON if requested (via the format parameter would be fine).
Is there any way to do this without explicitly defining the context switching rules in the init() part of every controller?
If you're going to be providing JSON, SOAP or XML-RPC, you're probably better off using Zend_Json_Server + Zend_Soap_Server instead of Zend_Controller_Action. Both the JSON and SOAP server classes can consume the same server class. No need for the overhead of routing, etc.
Matthew Weier O'Phinney's (Zend FW lead), site has a great post detailing the proper way of doing this: Exposing Service APIs via Zend Framework
you could try doing the context switch using a Zend_Controller_Front plugin on preDispatch.

Categories