I have a very old flat PHP project. I would like to modernize the source files without changing the big and old database structure. I found the PHP Framework Symfony Silex. I like the micro structure of this framework it's not so complicated to understand.
I have the following file structure:
- classes (The business logic)
- web (index.php and all my controllers)
- vendors
How can I include my business logic from the Silex app? Should I use require_once('classes/file1.php'); in my index.php?
How can I access the database from the business logic files?
Transitioning legacy code to a new framework is a difficult task. It's not going to be as simple as requiring your business logic files. Here's how I would go about it if I were in your position.
Spend some time learning Silex. Start by building a brand new test project with it to see how it works. It's best if you know how the framework is supposed to work before you try to integrate it with a legacy system. After you've tried it for a while, you can decide if Silex is a good fit for you.
Once you know how Silex works, you should get the Composer autoloader working with your code. Composer can load you business logic classes without having to use require.
Next, figure out how to work with your database. I see two options for you. You can either transition to Doctrine, or use your existing database access classes. The Symfony (and therefore Silex) ecosystem is oriented around the Doctrine ORM. Depending on your schema, you may be able to write Doctrine mappings for it. However, Silex is not tied to Doctrine, and you should be able to use your existing database access code. If you keep your existing system, you'll probably want to write a Silex ServiceProvider to integrate with it.
Next, the hardest part is probably going to be moving your business logic to Silex controllers. One thing to keep in mind is that you don't necessarily need to transition your entire project at once. Depending on how big your project is, you may want to transition a piece at a time.
I've got a huge site that has been written (in a very bad way) in symfony 1.4
now, I've been asked to make some substantial changes to the navigation flow, add some features and so on..
considering the effort, I was wondering if it would be better to take the radical decision to port the entire website to symfony 2.0, but I'm not sure how hard that it could be.
Has anybody ever done this before?
Do you have any suggestion to make for patterns to follow, or tutorials or doc or whatever?
You may wrap your legacy project in a brand new sf2 project, by using this bundle. This way, you'll be able to migrate your project one piece at a time, and new functionalities may be developed with sf2 as soon as you get the wrapper to work.
You may be interested by this post about migrating
Here's how I would go about it:
You need to learn and study some things first:
HTTP fundamentals
PHP namespaces, which are heavily used
Symfony2 documentation
Symfony2 documentation
Symfony2 documentation
PHPUnit documentation
Then when you get the hang of Symfony2, you need to find out what to reuse from your old project:
Models, business logic?
Did you use Doctrine in symfony? If yes, look at how to port your entities to Doctrine2, and learn about the differences. If you used Propel, I would look at switching to Doctrine2 and not use the PropelBundle, atleast until you get used to Symfony2. You can find better documentation and sample code out there for Doctrine2.
You also need to convert your old helpers classes to Symfony2 services.
Views?
Symfony2 uses Twig as templating engine, but you could go with pure PHP.
Controllers?
This should feel somewhat similar to symfony. The flow of Symfony2 matches the HTTP flow, meaning you get a Request object and must reurn a Response object.
It really depends on how well structured our old project is. Symfony2 is an entirely different beast than 1.0-1.4. I would probably not call it a port, but a rewrite - however, if your old project is well structured you could probably reuse quite a bit.
Without actually seeing your code, it's impossible to give a good answer on how hard it would be. It's very much doable, but there is no easy route. Symfony2 is, IMHO, the way of the future for PHP projects and in the end you will get a project that is much easier to maintain and support.
I've got a huge site that has been written (in a very bad way) in symfony 1.4
now, I've been asked to make some substantial changes to the navigation flow, add some features and so on..
considering the effort, I was wondering if it would be better to take the radical decision to port the entire website to symfony 2.0, but I'm not sure how hard that it could be.
Has anybody ever done this before?
Do you have any suggestion to make for patterns to follow, or tutorials or doc or whatever?
You may wrap your legacy project in a brand new sf2 project, by using this bundle. This way, you'll be able to migrate your project one piece at a time, and new functionalities may be developed with sf2 as soon as you get the wrapper to work.
You may be interested by this post about migrating
Here's how I would go about it:
You need to learn and study some things first:
HTTP fundamentals
PHP namespaces, which are heavily used
Symfony2 documentation
Symfony2 documentation
Symfony2 documentation
PHPUnit documentation
Then when you get the hang of Symfony2, you need to find out what to reuse from your old project:
Models, business logic?
Did you use Doctrine in symfony? If yes, look at how to port your entities to Doctrine2, and learn about the differences. If you used Propel, I would look at switching to Doctrine2 and not use the PropelBundle, atleast until you get used to Symfony2. You can find better documentation and sample code out there for Doctrine2.
You also need to convert your old helpers classes to Symfony2 services.
Views?
Symfony2 uses Twig as templating engine, but you could go with pure PHP.
Controllers?
This should feel somewhat similar to symfony. The flow of Symfony2 matches the HTTP flow, meaning you get a Request object and must reurn a Response object.
It really depends on how well structured our old project is. Symfony2 is an entirely different beast than 1.0-1.4. I would probably not call it a port, but a rewrite - however, if your old project is well structured you could probably reuse quite a bit.
Without actually seeing your code, it's impossible to give a good answer on how hard it would be. It's very much doable, but there is no easy route. Symfony2 is, IMHO, the way of the future for PHP projects and in the end you will get a project that is much easier to maintain and support.
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 want to convert an application from CakePHP to Code Igniter. Has anyone tried to do this? With my CakePHP application almost all the coding has been done in the controller layer, with the models pretty much exactly as they come out of baking.
CakePHP is newer, more feature rich and heavier than Code Igniter (CI is designed to have a much smaller footprint) so you will most likely find yourself creating functionality in CI to match cake's.
CakePHP also handles some core capabilities differently than CI. For example, routing functionality is handled via a dedicated class rather than per controller as in CI (via _remap).
I have never seen a tool that helps to automate such a conversion as it's rarely, if ever, done.
Taking all that into account, I believe the best approach is to rebuild your application from the ground up, drawing on your existing code and database schema.