Composer in a legacy Kohana project

require APPPATH.'../vendor/autoload.php'; One line in bootstrap.php. This month it became the whole strategy for a project we decided to keep on Kohana. The framework is quiet, the project is alive. These two facts have to coexist somehow. The plan: nothing new gets written the Kohana way. New dependencies come through Composer, and Kohana’s autoloader and Composer’s autoloader live together fine. First candidate was the HTTP client. We talk to two external APIs, and the code around Request_Client_External was not pretty. Guzzle is better in every way. But Guzzle does not spread through the codebase. There is an interface: ...

January 22, 2015 · 2 min · Murat Useinov

Host header is user input

$link = 'https://'.$_SERVER['HTTP_HOST'].'/reset/'.$token; I wrote this line. More than once. It builds the link for a password reset email, and it looks like it reads something about the server. It does not. Host comes from the client, same as any other header. Kohana 3.3.4 shipped this month with a fix around exactly this, and the topic is bigger than one framework. The attack is short. Someone requests a password reset for your email address and puts his own domain into the Host header. The application trusts the header, builds the link, sends it. You receive a real email from a real site with a link to evil.example and your real token in the path. You click. He collects the token. Host header poisoning, and no framework protects you from it out of the box. ...

December 23, 2014 · 2 min · Murat Useinov

Symfony 2.6: dump() and boring upgrades

dump() instead of var_dump(). Symfony 2.6 came out at the end of November, and this is the visible gift: VarDumper. Collapsible output, clickable class names, works inside the toolbar. A small thing, used fifty times a day. Tools like this improve life more than big features do. But the important story in 2.6 is not a feature. The release notes read like a preparation checklist for Symfony 3: deprecations, everywhere. ...

December 18, 2014 · 2 min · Murat Useinov

Symfony best practices: defaults, not laws

One AppBundle. That is the line in the official Symfony Best Practices book I read twice. For years the answer to “how many bundles” was “as many as you have features”, and here the framework’s own book says: one. The book came out this autumn. Worth reading even if you are not on Symfony, because the interesting part is the change of tone. The old Symfony way: everything is a bundle. Your application is bundles, reusable, configurable, with their own extensions and semantic configuration. Very flexible. And for a normal business application, mostly ceremony. You write a configuration class for code that will never leave this one project. I wrote such classes. Three of them. None was ever reused. ...

December 14, 2014 · 2 min · Murat Useinov

Debug toolbar in production is a gift to strangers

/_profiler on a live site. Type it after any Symfony domain and sometimes it answers. This autumn the story went around, and I will not retell it. The lesson is bigger than one framework. Think what a profiler actually stores. Every SQL query with parameters. Cookies and session data. Routes, controller names, request headers. Sometimes config values. A full X-ray of your application, nicely formatted, with search. Now count how many sites have /_profiler or a debugbar open to the world because someone deployed with app_dev.php, or left debug = true in the production config. Not a rare exotic mistake. I saw it. I made it once, on a staging server that stayed reachable from outside longer than anyone planned. ...

December 9, 2014 · 2 min · Murat Useinov

PHP 5.6: small syntax, big TLS surprise

A nightly cron failed silently for two days. That was our PHP 5.6 upgrade. 5.6 is out since the end of August, and we moved one production project this month. The syntax part is pleasant and minor. Variadics: function log_all($level, ...$messages) { } Argument unpacking with ...$args on the call side. Constant expressions in defaults. use function for importing functions. All nice. None of it changes your architecture. You will use variadics maybe twice a year and be happy both times. ...

December 5, 2014 · 2 min · Murat Useinov

Services instead of fat controllers

120 lines in one action. Order confirmation: load the order, charge the card, send the email, render the page. It ran fine for a year. Then a console script needed the same operation, and the action turned out to be glued to SMTP, to the database and to the HTTP request. All at once. Symfony people talk about dependency injection so much it sounds like religion. It is one simple idea: a class receives its dependencies and does not create them. ...

December 2, 2014 · 2 min · Murat Useinov

Queues in Laravel 4.2: the user should not wait for your SMTP

1.8 seconds for one registration request. I put a timer around it on a project last month. 1.5 of those seconds was the welcome email going out over SMTP. The user waits almost two seconds and looks at a spinner, for a handshake with a mail server he will never hear about. Laravel 4.2 makes the fix one line: Queue::push('SendWelcomeEmail', array('user_id' => $user->id)); The controller returns in 300 ms. A worker picks the job up and sends the email. php artisan queue:listen to start, beanstalkd or Redis behind it, the failed_jobs table for jobs that died. ...

November 27, 2014 · 2 min · Murat Useinov

Composer next to Kohana bootstrap

One line in bootstrap.php, above Kohana::init(): require DOCROOT.'vendor/autoload.php'; That is the whole integration. Kohana keeps its modules and its underscore autoloader. Composer brings Packagist. Two autoloaders in one process, and they do not collide: Composer packages use namespaces, Kohana classes have underscores, the lookups never meet. { "require": { "guzzlehttp/guzzle": "~5.0" } } This setup runs in production on one of my projects for a few months. Zero problems from the autoloading side. The problems, when they came, were from me. ...

November 23, 2014 · 2 min · Murat Useinov

Kohana is not developed anymore. Now what

The commit log of kohana/kohana on GitHub. I opened it in the summer and counted: a few merges a month, then fewer, then nothing. This year the official development basically stopped. Our projects did not stop working on that day. But the question came to my inbox three times since, so here is the answer. What to do with a working Kohana product depends on which of four situations you are in. ...

November 19, 2014 · 2 min · Murat Useinov