A montreal-based newspaper recently released a new mobile product to read news. It’s very nice, but it cost them 40 million and took 3 years to ship, with some 100 people on the team. My company has enough experience with news corporations and other industries to know that there was a lot of waste. My associate stated on social media that he could save them millions on their next project. It’s what we specialize in: generating millions in ROI for our clients.
Without hesitation, developers of that product reacted. They were outraged, saying that the budget was entirely justified due to the complexity of the project. The fact that they felt targeted at all is a bad sign, because we certainly didn’t set out to lay blame. To deny that anything at all could have been done better is a lie to oneself and to the client. Have you ever finished a project thinking how things could have gone better? Hopefully you always do. I have been in the field since 1997 and I still improve.
So why would a developer fervently defend a ridiculous budget and what does it mean to the company?
Such a reaction is mostly due to an inflated ego. Everyone likes to think that their project is ultra-complex, the hardest thing ever built. But complexity is relative to one’s experience. An information system built on PHP with a mobile app on top is hardly worth 40 million unless a lot of the money was spent unwisely, in one way or another.
Regardless of what caused the project to blow out of proportion, the fact that people would defend such a big budget should alarm the company. What it means is that these developers would gladly use up all of the company’s resources if they could justify it. It means that they’re too good to have done anything better. It means that they would turn down expert advice even if it meant saving a lot of money for their client.
Why not save money? After a quick research into the names of the developers who replied, it turns out that they are all contractors, not employees. Indeed, longer projects gives them job security. Should an expert come in and find ways to cut production time in half, they would be looking for a new “job” sooner. Not all contractors act this way, but these clearly don’t have their client’s best interests at heart.
That does not mean that companies should not hire contractors. It means that it’s always better to have an expert on board who can see problems before they happen and who can save the company some 20 million or more. Don’t ignore your ROI. Don’t be the John Carter of IT.
- Page File
Package:Summary:Generate pages and save to filesGroups:Author:Description:This class can Generate pages and save to files...
Read more at http://www.phpclasses.org/package/8002-PHP-Generate-pages-and-save-to-files.html
- PHP Collections Framework
Package:Summary:Manipulate collections of objects like Java and C#Groups:Author:Description:This package can be used to manipulate collections of objects like Java and C#...
Read more at http://www.phpclasses.org/package/8008-PHP-Manipulate-collections-of-objects-like-Java-and-C-.html
Package:Summary:Query MySQL databases using parametersGroups:Author:Description:This class can query MySQL databases using parameters...
Read more at http://www.phpclasses.org/package/8011-PHP-Query-MySQL-databases-using-parameters.html
- MySQL Database usage
Package:Summary:Query MySQL database tablesGroups:Author:Description:This class can query MySQL database tables...
Read more at http://www.phpclasses.org/package/8009-PHP-Query-MySQL-database-tables.html
- PHP Compare Objects
Package:Summary:Compare objects using reflectionGroups:Author:Description:This class can compare objects using reflection...
Read more at http://www.phpclasses.org/package/8012-PHP-Compare-objects-using-reflection.html
- PHP Curl Parallel Requests
Package:Summary:Send multiple HTTP parallel requests with CurlGroups:Author:Description:This class can send multiple HTTP parallel requests with the Curl extension...
Read more at http://www.phpclasses.org/package/8014-PHP-Send-multiple-HTTP-parallel-requests-with-Curl.html
Package:Summary:Parse an URL and extract its partsGroups:Author:Description:This class can parse an URL and extract its parts...
Read more at http://www.phpclasses.org/package/8005-PHP-Parse-an-URL-and-extract-its-parts.html
- PHP Reduce JSON
Package:Summary:Compress JSON data using the reduced JSON formatGroups:Author:Description:This class can compress and decompress JSON data using the reduced JSON format...
Read more at http://www.phpclasses.org/package/8007-PHP-Compress-JSON-data-using-the-reduced-JSON-format.html
- File Reader
Package:Summary:Read and search text filesGroups:Author:Description:This class can read and search text files...
Read more at http://www.phpclasses.org/package/8006-PHP-Read-and-search-text-files.html
In a new post to his site Tom Butler gives some reasoning as to why he thinks PSR-0 is shortsighted and some examples of a possible better alternative.A little background for those unaware of what PSR-0 is: There's a self-declared PHP "standards" group called PHP-FIG attempting to push several "standards" throughout the PHP community. [...] I have little interest in debating the politics behind pushing standards or whether small groups of developers trying to make decisions that affect the entire community is good or not, but I do object to the PSR-0 standard itself. My issues are purely practical, PSR-0 reduces flexibility and makes life more difficult for developers
While he likes the idea of a standard way to be able to include third-party libraries that can be reused in multiple systems, he suggests that it answers the wrong question. In his view, it should be up to the library/tool developers to ensure the structure of their code to work with a standard, not the other way around. He points out that a "standard" is something that should apply to all situations and some of the workarounds that are needed for PSR-0 negate this idea.
In his alternative method, he suggests an "Autloadable" interface that can be implemented by the library/tool that includes a "load" method to handle the actual class loading. Then this autoloader would be registered via a json configuration file for the package. This allows the developer to control the loading and place any exceptions they might need into their own logic instead of trying to work around possible issues with the PSR-0 loading scheme.PSR-0 is a bad solution to a good problem. If you take anything from reading this post, remember this: If the standard defined how autoloaders could be extended, rather than how autoloaders worked, then each library or vendor could provide its own extension to the autoloader and everyone would be happy. Link: http://r.je/php-psr-0-pretty-shortsighted-really.html
On Reddit's PHP section there's a discussion happening about dependency injection versus service locators in two popular PHP frameworks - Zend Framework 2 and Symfony 2 (and how they're not really DI at all).Both ZF2 and Symfony 2 offer the same behavior: if I'm in a controller, and I want to use a service, I have to get it from the container with $this->get('my_service'). As such, the controller is not using DI, this is the service locator pattern. Controllers become more difficult to tests because of that, and they depend on the container now. I wonder why both frameworks didn't go further: why not treat controllers like services and use dependency injection on them. In other words: if a controller needs a service "A", then it should get it in the constructor, or through setter/property injection.
The comments talk some about the "controller from the DI container" idea, some other ways around the problem and some clarification as to what the frameworks are actually doing related to the container injection.Link: http://www.reddit.com/r/PHP/comments/1caidn/dependency_injection_in_zf2_and_symfony_2_are
Good enough of a reason to write down or re-cap some things I've learned with or about Vagrant over the last two years.Base boxes
There are lots of base boxes available, but don't be tempted to rely on them (e.g. via
- Vagrantbox.es doesn't actually mirror images and that is a huge pain.
- Available base boxes tend to be outdated. (Think kernel, packages, etc.) Running updates each time you provision is painful.
- Available base boxes use U.S. mirrors only/mostly/always — because we all live in the U.S. of A..
- Your VirtualBox guest additions may not match with your system and this may create random issues.
At EasyBib, we use bento and we created a definition which replaces the sources with Ubuntu's nifty mirror syntax (since we're pretty distributed at times, everyone appreciates this) and upgrades the base system. Either one of these tools introduce more Ruby into your organization and you may think "WTF — why do I need this?!", but the clear advantage is that no one has to write down a lot of steps how to recreate these boxes and anyone can do it.
In bento's case, the requirement is Ruby 1.9.1+ (getting this installed is IMO the hardest) and bundler.
bundle install in your bento-clone gets you everything needed and then the three commands require build, validate and export a box which is ready to use. Ensure to put whatever you need into the definition — for example in the
update.sh. Avoid too many manual steps before you export because the next person will have to know and repeat them. Bento serves as documentation as well.
I version our boxes with like easybib-something-10.04.4_vbox-4.1.8_0.1.box and upload them to an S3 bucket. The first number is the Ubuntu release and the second is the version of the VirtualBox guest additions. Simple. The third version is our internal iteration — typically a base box isn't perfect from the beginning while e.g. the Ubuntu and VirtualBox part are settled, there might be other improvements. With an extra version you avoid conflicts and extra work like
vagrant box delete etc. and ensure the latest box is always used.
Also — in case the software stack is very different across your projects, it also helps to to create different boxes which come with different software pre-installed.Standardize on versions
Vagrant and VirtualBox have frequent releases. I suggest to standardize on one so members of your team don't have random issues at hand and fires to fight.
Even for a small team of up to ten developers this makes a lot of sense. Because people tend to add a lot of randomness anyway — different hardware, operating systems and so on. Fight only the battles you want to fight, and deploy otherwise.
Vagrant also recently went from being a rubygem to providing installers. I haven't had the time to roll this out yet, but I expect this to help as well since at least as far as ruby is concerned all the dependencies are bundled.
This of course still implies that testing is required so you and your team don't walk into a stupid little regression and waste away the day trying to figure out what went wrong. And of course even if Vagrant is smoother, it still leaves you with VirtualBox and tools like bento and plenty of potential breakage.Chef Versions
On a side-note — Chef 10 and 11 may also introduce a lot of breakage in recipes. It helps to roll your base box with a specific version as well. With bento the work-around was pretty straight forward: I replaced the
chef-client.sh and installed Chef 10 (instead of 11 — or whatever the latest is).
In theory, it's alright to run with different guest additions in a box than the version of VirtualBox you have installed on the host. It should at least match the main release — for example: 4.1.8 guest additions and 4.1.12 VirtualBox should do fine. That's a big should though, because it also may cause random issues like crashes and hangs.
If you don't wa
Truncated by Planet PHP, read more at the original (another 5226 bytes)
On PHPMaster.com today there's a new tutorial for the Twig templating users out there showing you how to extend your templates via inheritance, filters and functions - all abilities already built in to the tool.When working within an MVC architecture, it's common to use a template library to populate the dynamic content of our views. There are dozens of such libraries available for PHP, but Twig is one of the standouts because of the ability to extend core features with custom implementations. In this article we'll explore how Twig templates can be extended using template inheritance, filters, and functions.
He starts first with some of the common limitations of templating frameworks (extension) and how Twig gets around this. He shows the use of the "extends" keyword and the "block"/"endblock" for splitting up the page into reusable chunks. He also shows how to use filters and functions in your Twig tags, allowing for more customized content and functionality for your output.Link: http://phpmaster.com/extending-twig-templates-inheritance-filters-and-functions/
He walks you through the process of setting up your Google Drive account API access and where to find the data you'll need to make the connection. He then links over to his project that makes the backup a simple few lines of code (mostly configuration) of a backup path of your choice out to the remote Google Drive account.Link: http://systemsarchitect.net/automated-backups-to-google-drive-with-php-api
Matt Setter has a quick new post that suggests a way you can get more done with less work - simplicity.Though we can do so many things simultaneously - should we? Does it actually reduce effectiveness and productivity which are the antithesis of professional application development? [...] I had the thought, as is common in a western-based mentality, that to be busy, to be industrious, to try and multi-task a series of independent tasks and projects simultaneously was the right thing to do. It's meant to be a simple formula: "Greater productivity = Greater self-worth right?" Sounds almost like Thatcherism. I felt that this was not only right, but the sign of an intelligent and sophisticated developer, who truly had honed his craft. Perhaps you've felt the same at one time or another?
He points out that, while it's very easy for developers to fall into this trap and way of thinking, it's not sustainable. It leads to stress, bad code and even - possibly - an even higher bug count. Instead he suggests the good standby idea of "KISS" (essentially, simplicity).Instead of trying to do everything at once - I stopped and decided to only do one thing at once. And that one thing, had my full attention and focus. When it was done, I then moved on to the next one. Not before and not after.
He includes some of his own experience trying to apply this in a Zend Framework 2 application.Link: http://www.maltblue.com/software-engineering-2/how-simplicity-leads-to-greater-productivity-quality-and-satisfaction
- fresque/fresque (1.1.5)
A command line tool to manage your php-resque workers
- phundament/p3pages (0.10.4)
- rhumsaa/uuid (2.1.0)
A PHP 5.3+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).
- piwik/piwik (1.12-b10)
Open Source Real Time Web Analytics Platform
- devhelp/calendar (1.0.4)
- campaignmonitor/createsend-php (v3.1.0)
A php library which implements the complete functionality of the Campaign Monitor API.
- sail/useragent (1.0.0)
Library to detect the browser and all its info (OS, Platform, ...)
- imbo/imbo-zf2 (1.1.0)
Imbo module for Zend Framework 2
- satooshi/php-coveralls (0.1.0)
- mparaiso/routeconfigserviceprovider (v0.0.8)
Route config file support for Silex framework
- z_bodya/yii-image (1.0.0)
Port of Kohana Image Library to Yii
- z_bodya/yii-tinymce (1.0.0)
Extension to use TinyMce with Compressor, SpellChecker and FileManager
- z_bodya/yii-gallery-manager (1.0.0)
Extension for yii, that allows to manage image galleries
- z_bodya/yii-elfinder (1.0.0)
Extension to use elFinder 1.x file manager in yii application
- z_bodya/yii-datetimepicker (1.0.0)
Datetime picker input widget
- nelmio/alice (1.4.0)
Expressive fixtures generator
- z_bodya/yii-coordinatepicker (1.0.0)
Widget to pick coordinates using google map in modal window
- z_bodya/yii-chosen (1.0.0)
Anouther chosen extension, provides easy to use InputWidget
- orno/di (v1.1.4, v1.1.3, v1.1.2, v1.1.1)
Orno Di is a small but powerful dependency injection container with automatic resolution of dependencies.
- uestla/twigrid (0.9.1)
Experimental DataGrid for Nette Framework
- cakedc/migrations (2.2.1)
Migrations Plugin for CakePHP
- lexik/translation-bundle (v1.4.1)
This bundle allow to import translation files content into the database and provide a GUI to edit translations.
- rampage-php/framework (1.0.0-alpha1)
Rampage PHP Framework based on Zend Framework 2
- rampage-php/composer-module-installer (1.0.0)
Composer installer for rampage-php framework modules
- brainbits/transcoder (1.1.1)
Library for encoding, decoding transcoding data.
- bear/resource (0.7.5)
RESTful service layer framework
- hwi/oauth-bundle (0.2.2)
Support for authenticating users via oauth in Symfony2.
- widget/widget (0.9.2-beta)
A new way to write PHP
- lcobucci/action-mapper (1.0.0alpha7)
Front controller framework for PHP 5.3+ applications
- lcobucci/di-builder (1.0.0)
Dependency Injection Builder for PHP 5.3+ applications
- br/signed-request-bundle (0.3)
Symfony2 Bundle that provides request and response signing
- bluedogtraining/guzzle-eway (v2.1.1)
A Guzzle client for interacting with the Eway Direct Transactions API
- pcsc 0.2
Fixed compile error on >= PHP5.4 and added w32 support
- couchbase 1.1.4
- Prototype trying to get the thing working for PECL
- Reset the error code between each request of a persistent connection
- Report libcouchbase version in phpinfo
- Remove gettimeofday implementation for win32
- PCBC-206: Prototype for configuration caching
- Fixup memory allocation for URL path
- PCBC-186: Add method to list all design docs
- PCBC-178: Add support for connection_timeout
- Update GetReplica test
- PCBC-218: Detect invalid characters in CAS
- Add bucket manipulation example
- PCBC-172: Add design document examples
- PCBC-191 Don't coredump for invalid argument
- Update the list of supported PHP versions
- mongo 1.3.7
* [PHP-700] - 'MongoCursorException' with message '127.0.0.1:27017: request/cursor mismatch
PHP is the world’s #1 programming language for creating websites. But it’s capable of so much more. How about real-time processing the social firehose? :)
Thanks to Brighton PHP for hosting this talk last month.
Sprout is a project dedicated to a nested key-value pair programming language native to the Entity Attribute Value database model. Its environment is a Relational Database Management System, specifically Postgres 9. It is implemented with Procedural SQL and employs a key-value translator vernacular to EAV data model. The model provides storage of objects, object metadata definitions and program code. Sprout executes requests via SQL client interface and returns objects of various types. It has characteristics of a column-oriented database.
He jumps right in and gets into the configuration (the composer.json file) and using it to describe the package. He shows how to set up "required" resources complete with version number information. There's a bit about setting up autoloading and classmaps too. He then moves on to getting the tool installed and using the composer.json definition to load in needed packages (and development ones if needed).Link: http://daylerees.com/composer-primer
In the interview he answers questions about:
- His background and how he got started with PHP
- What he sees as the good and bad parts of the language
- Some suggestions for developers wanting to learn
- What frameworks/unit testing tool and CMS he recommends
There's also a section more specifically focused on the Brazilian PHP community, PHP conferences and some of the things he's learned in his time in the wider PHP community.Link: http://7php.com/php-interview-manuel-lemos
Fabien Potencier (of the Symfony framework) has a new post to his site talking about a philosophy that the Symfony framework community should work towards, providing stability over features.Long story short: in the coming months, the Symfony core contributors should focus their efforts toward stabilizing the existing features instead of working on new ones. At this point, backward compatibility and stability are more important than everything else.
He highlights some of the points that come along with this effort including less refactoring for the sake of refactoring, fixing more bugs/edge cases and writing more tests/documentation. He gets into some of the specifics of this kind of thinking and points out the things that can and can't be changed during this time. He talks more about stability and suggests that not only can it help enhance performance but it could also help motivate more projects/corporate users to start using the framework.Link: http://fabien.potencier.org/article/68/about-symfony-stability-over-features
On SitePoint.com today they've posted the transcript of a "Talk with the Experts" session they did with Lorna Mitchell (instructor of their recent OOP sessions). The transcript includes questions and answers to those in attendance as well as some good links and advice.Last Thursday I broke with tradition slightly and ran a Talk with the Experts session in the evening (down under), making it a bit more time-zone friendly for our UK audience. It also meant that I was able to swap my usual coffee for a wine, which probably made the session run a bit more smoothly. The subject was PHP and our expert was Lorna Mitchell, tutor of Object-oriented PHP and co-author of PHP Master: Write Cutting-edge Code.
The transcript starts with a collection of some of the links provided during the discussion and then runs through the entire conversation. There's some good advice in there, especially if you're relatively new to the world of PHP object-oriented programming.Link: http://www.sitepoint.com/what-happened-when-we-talked-php-with-the-experts
- herrera-io/wise (1.1.2, 1.1.1)
Symfony Config for everyone else.
- instinct/types-autoboxing (v1.0.0-BETA1)
Wrapping primitive types into objects automatically
- kamisama/cake-resque (3.3.1)
A CakePHP plugin for creating background jobs with Resque
- fresque/fresque (1.1.3)
A command line tool to manage your php-resque workers
- kamisama/php-resque-ex (1.2.4)
Redis backed library for creating background jobs and processing them later. PHP port based on resque for Ruby.
- titon/test (0.7.0)
The Titon test package provides classes and fixtures used for test cases. This should not be used in production.
- mobiledetect/mobiledetectlib (2.6.0)
Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.
- blake/symfony-extensions (v1.0)
Provides some extra goodies to the base controller class and Doctrine entities in Symfony 2.
- lyrixx/lifestream-silex-provider (1.0.0)
Silex prodivder for lyrixx/lifestream
- mjohnson/transit (1.1.0)
A file uploader, validator, importer and transformer library.
- taluu/link-tpl (1.14.0)
Templating Engine for PHP
- cgm/config-admin (1.2.1)
ZF2 module for easy administration of application settings
- fg/essence (1.4.0)
Extracts informations about medias on the web, like youtube videos, twitter statuses or blog articles.
- webcodr/collection (2.1.2, 2.1.1)
Collection library for PHP
- webcodr/mango (0.6.13, 0.6.12, 0.6.11, 0.6.10)
A MongoDB object document mapper for PHP
- bear/package (0.6.6)
BEAR.Sunday application package
- devhelp/calendar (1.0.3)
- tui/session-bundle (1.0.1, 1.0.0)
Adds a session expiry listener
- toddish/verify (v1.1.1)
A simple authentication bundle for Laravel 4. It features roles, permissions, password salting and is fully extendable.
- simplon/helper (0.5.5)
General helpers which come-in helpful.
- matthimatiker/molcomponents (1.4.5-beta1)
Library with use-at-will architecture that extends the functionality of Zend Framework 1. Main features: Improved bootstrapping with lazy loading of resources, declaration of request parameters as argument in controller actions, advanced form creation and validation, mail templates, lightweight controller testing.
- n98/magerun (1.62.1, 1.62.0)
Tools for managing Magento projects and installations
- craue/formflow-bundle (1.1.1)
Multi-step forms for your Symfony2 project.
- intervention/image (1.3.8)
Image handling and manipulation library with support for Laravel 4 integration
- mparaiso/routeconfigserviceprovider (v0.0.6, v0.0.7, v0.0.5)
Route config file support for Silex framework