THE STATE OF PHP
Composer, PSR, Frameworks and more
Juan Manuel Torres/@onema
Eric Van Johnson/@shocm
Eric Van Johnson/@shocm
FOLLOW ALONG:
http://slides.com/onema/the-state-of-php/live
CODE ALONG:
http://3V4L.org/
Juan Manuel Torres
@onema
Born and raised in Bogotá Colombia
30 largest cities in the world, 7 Mill, 8612 ft, 58 °F
Software Engineer
MS Computer Science SDSU, 5+ years of experience
PHP and me
Started using PHP in 2001
Eric Van Johnson
PHP developer, architect and organizer of SDPHP
@shocm
TO PREVENT YOU FROM FALLING ASLEEP
FOLLOW ALONG:
http://slides.com/onema/the-state-of-php/live
CODE ALONG:
http://3V4L.org/
FRAMEWORKS
"Standing on the shoulder of giants"
ON THE SHOULDER OF
GIANTS
Using established frameworks leverages the power of the community for stability, enhancements, fixes, and support. “Standing on the shoulder of giants”
Frameworks speed up your development process by giving you a strong codebase to build from. Typically frameworks have defined coding standards and approach to development. This can typically be one of the larger challenges when using a new framework.
I usually categories frameworks in one of three groups.
MICRO FRAMEWORKS
Micro Frameworks:
Micro Frameworks come with some very core functionality such as some sort on database interface, router, and a way to handle templating. Usually these Micro Frameworks can be extended out to full fledge frameworks.
One big advantage to a Micro Framework is that they can often be integrated into an existing application with little effort. And Micro Frameworks usually don’t require a lot of effort to pick up and start working with.
Some examples of a micro framework would be Silex (baby brother of Symfony), Fat-Free, and Slim.
FULL FLEDGE FRAMEWORK
OR GENERAL FRAMEWORK
The general PHP Framework has a full development practice associated with it. Many adhere to a Model-View-Controller (MVC) approach. Unlike Micro Frameworks, a general Framework will come with a host of functionality for things like JSON or handling Files and typically will be packaged with their own templating engine. It’s typically more difficult to “integrate” a full fledge Framework into an existing application, These frameworks tend to need to have the application developed within them.
Because of this, these frameworks can take a little effort to understand. Especially if you struggle getting your head around some of the core development approaches such as MVC.
Examples of General Frameworks would be Laravel, CakePHP, Yii, FuelPHP, and CodeIgniter.
ENTERPRISE FRAMEWORKS
Enterprise Frameworks are designed with Business Logic in mind and have a strong focus on performance and optimization. Heavy in libraries and interfaces these frameworks can be a lot to take on and learn. The biggest advantage of Enterprise Frameworks is that there is commercial support for them. Many have well defined training tracks and certification processes.
Most Enterprise Frameworks are Open Source and can be used for free but having a Company “own” the project means there can be one trusted source for things like patches.
Examples of Enterprise Frameworks would be Zend Framework 2 and Symfony.
ADVANCED FEATURES
NAMESPACES
Introduced in PHP 5.3, Namespaces help to bring logic to the chaos of 3rd party libraries.
PHP being a little late to the party with Namespaces as many other languages already use them. Namespaces allows you to define multiple methods with the same names.
EXAMPLE
class User{}
To implement you would do something like this
$user = new User();
class User{}
To implement you would do something like this
$user = new User();
The problems
- A class like User very common
- A 3rd party library can cause these sorts of naming conflicts
SOLUTION
Namespaces help to fix that. Let’s say we develop, or deploy, a library for GeekGirl which also has the method “User”. Using Namespaces we might introduce that like this.
First we would create our namespace :
<?php
namespace GeekGirl;
class User
{
// GeekGirl User Code
}
<?php
namespace GeekGirl; class User
{
// GeekGirl User Code
}
IMPLEMENT
Now that we have a GeekGirl Namespace defined,
we can use it in our code
by addressing the Namespace itself
<?php
$user = new GeekGirl\User();
we can use it in our code
by addressing the Namespace itself
<?php
$user = new GeekGirl\User();
WORKING
INSIDE A NAMESPACE
When you define a namespace you are working in, then all methods are relative to that name space. But you still have access to the Global namespace.
namespace GeekGirl;
$gg_user = new User(); // User Class in the GeekGirl namespace
$user = new \User(); // User class from the Global namespace
This means you can also address methods in other libraries.
namespace GeekGirl;
$user = new \SDConference\User();
INCLUDE
AND ALIAS NAMESPACES
There is also a shortcut for referencing these hierarchical namespaces if you plan on implementing them more than once. You can use the ‘use’ command
namespace GeekGirl;
use SDConference\User;
$user = new User(); // Using User method from SDConference
We can also give the method we are importing an alias with the ‘as’ keyword. So for example we can do something like
namespace GeekGirl;
use SDConference\User as SdConfUser;
$user = new User(); // GeekGirl Namespace
$sd_user = new SdConfUser(); // SDConference
TRAITS
A trait is like a abstract class but can not be instantiated on its own. Traits are a sort of workaround for PHP's
lack of support for multiple inheritance.
lack of support for multiple inheritance.
trait Magic {
/**
* A block of code that does a lot of work
* need by several other classes
*/
public function foo() {}
}
class Reader extends BaseReader {
use Magic;
}
class Writer {
use Magic;
}
MULTIPLE TRAIT IMPORTS
EXAMPLE
trait Hello {
function sayHello() {
return "Hello";
}
}
trait World {
function sayWorld() {
return "World";
}
}
class MyWorld {
use Hello, World;
}
$world = new MyWorld();
echo $world->sayHello() . " " . $world->sayWorld(); //Hello World
ANONYMOUS FUNCTIONS
In computer programming, an anonymous function is a function definition that is not bound to an identifier.
- Wikipedia
function doMath(callable $function, $a, $b) { return $function($a, $b); } doMath(function($a, $b) { return $a * $b; }, 9, 2); // 18
LAMBDAS
Lambda is an anonymous function that can be stored in a variable and passed as an argument
function sum ($a, $b) { return $a + $b; } $division = function($a, $b) { return $a/$b; }; function doMath(Closure $function, $a, $b) { return $function($a, $b); } doMath($division, 9, 3); // 3
CLOSURES
A closure is a lambda function that is aware of its surrounding context
- Fabien Potencier
$division = function($a, $b) { return $a/$b; }; function doMath(Closure $function, $a, $b) { $result = $function($a, $b); return function() use ($result) {echo $result;}; } $callback = doMath($division, 9, 3); $callback(); // 3
EXAMPLE
$division = function($a, $b) { return $a/$b; }; function doMath(Closure $function, $a, $b) { $result = $function($a, $b); return function() use ($result) {echo $result;}; } $callback = doMath($division, 9, 3); $callback(); // 3 $callback = doMath(function($a, $b) { return $a * $b; }, 9, 2); // 18 $callback();
COMPOSER
Dependency Manager for PHP
ADDING DEPENDENCIES
IS EASY
- Copy / Paste
- Do it yourself
- Git Submodules
MANAGING THEM CAN BE
VERY MESSY
ISSUES
- Your app depends on libraries
- Keep these libraries up to date
- Libraries also depend on other libraries
WHAT IS COMPOSER?
- Resolves inter-package dependencies
-
Installs all dependencies
- Create an autoloader
- Follows PSR-0 and PSR-4
- Inspired by
- Node.JS NPM
- Ruby Bundler
HOW TO GET STARTED
WITH COMPOSER
Install Composer in a local directory:
curl -s https://getcomposer.org/installer | php
Install Composer globally:
curl -s https://getcomposer.org/rinstaller | php
sudo mv composer.phar /usr/local/bin/composer
HOW TO MANAGE
DEPENDENCIES
- Create a sample project and
-
Add a composer.json file
- Require specifies packages and version
{ "require": { "php": ">=5.4", "guzzlehttp/guzzle": "4.0.*" } }
INSTALL IT
USE IT
<?php // test.php require_once __DIR__.'/vendor/autoload.php'; $client = new GuzzleHttp\Client(); $response = $client->get('https://google.com'); echo $response->getBody();
FIG & PSR
Community driven standards
FRAMEWORK
INTEROPERABILITY GROUP
- Finds commonalities between different Open Source projects
-
Develop standards to better work together
PHP STANDARDS
RECOMMENDATIONS (PSR)
-
These are recommendations
- PSR-0 The Basic Autoloader
- PSR-1 Basic Coding Standards
- PSR-2 Coding Style Guide
- PSR-3 Logging
- PSR-4 Autoloader Revised
PSR-0 (AUTOLOADING)
Standard for class naming and autoloading
1. Fully-qualified namespace and class must have the following structure
\{Vendor Name}\({Namespace}\)*{Class Name}
2. Each namespace separator is converted to a directory separator when loading from the file system/VendorName/Namespace/ClassName.php
WHAT ARE NAMESPACES?
In practice, it is a language supported way to shorthand long class name and prevent conflicts
class Foo_Bar_Database_Model {...}
namespace Foo\Bar\Database; class Model {...}
use Foo\Bar\Database\Model; use Custom\Database\Model as CustomModel; class MyController { $model = new Model(); $customModel = new CustomModel(); }
PSR-1 (CODING STANDAR)
Coding conventions to ensure high level of technical interoperability between share PHP code.
This enables code to run in servers and environments other than the original dev environment.
-
MUST use <?php and <?= tags only
-
MUST use only UTF-8
-
Files SHOULD either declare symbols or cause side effects
- Classes and Namespaces MUST follow PSR-0
- Class names MUST be declared in StudlyCaps
- Class constants MUST be UC separated by underscores
- Method names MUST be declared in camelCase
PSR-2
(CODING STYLE GUIDE)
namespace Vendor\Package; // <== Line break use OtherVendor\OtherPackage\BazClass; // <== Line break class Foo extends Bar implements FooInterface { // <== Brace in new line public $var; // <== Visibility public function sampleFunction($a, $b = null) // <== Must not have space { // <== Brace in new line if ($a === $b) { // <== Brace in same line bar(); // <== 4 space indentation } else { BazClass::bar($arg2, $arg3); } } // <== Must be in new line }
PSR-3 (LOGGER) &
PSR-4 (AUTOLOADER)
THE PHP STANDARD
LIBRARY
PHP comes with a set of functionality know as the PHP Standard Library or SPL. Some of this functionality is widely used but some of it isn't.
DATA STRUCTURES
These are amongst the least know functionality in the SPL, yet they can be very helpful.
Data structures implement the Iterator and Countable interfaces which enable them to be traversed using foreach() and counted using the count().
Some notable Data Structures are:
- SplDoublyLinkedList
- SplHeap
- SplFixedArray
SPL DOUBLY LINKED LIST
- You can move forward or backwards
- Memory efficient
- Random reads can be slower that array
- Can be used as a queue or a stack
SPL HEAP
- Complete binary tree that satisfy the heap property
- Can insert directly into stored position under ideal conditions
- Is an abstract class
- Must implement class compare
- Return 1 if value 1 > value 2
- Return 0 if value 1 == value 2
- Return -1 if value 1 < value2
- You can compare anything, these definitions are up to you
WORLD CUP EXAMPLE
class FifaRankingHeap extends \SplHeap {
protected function compare($value1, $value2) {
return $value1['points'] - $value2['points'];
}}
$heap = new FifaRankingHeap();
$heap->insert(array('country' => 'Colombia', 'points' => 1137));
$heap->insert(array('country' => 'Uruguay', 'points' => 1147));
$heap->insert(array('country' => 'Argentina', 'points' => 1175));
$heap->insert(array('country' => 'Brazil', 'points' => 1242));
$heap->insert(array('country' => 'Portugal', 'points' => 1189));
$heap->insert(array('country' => 'Germany', 'points' => 1300));
$heap->insert(array('country' => 'Switzerland', 'points' => 1149));
$i = 2;
foreach ($heap as $country) {
echo $i++.$country['country'].' has '.$country['points'].' points.';
}
SPL FIXED ARRAY
Regular arrays are very efficient to read an write, but they can utilize a lot of memory.
SplFilsedArray is an alternative that performs very well and uses less memory;
Unfortunately SplFixedArray can not be used as an associative array and it must have a fixed size.
EXAMPLE
class Test { public function __destruct(){ echo "Destroying class ".__CLASS__; } } $array = new \SplFixedArray(6); $array[5] = new Test(); $array->setSize(5); // Destroying class Test
QUESTIONS?
THE END
REFERENCES
- http://code.tutsplus.com/tutorials/psr-huh--net-29314
- http://www.slideshare.net/lonelywolf/php-psr-standard-2014-0122?qid=541b412b-0812-4e28-9003-19867b79ec09&v=qf1&b=&from_search=1
- http://www.slideshare.net/jeremykendall/composer-devops20130716
- http://www.php-fig.org/
- http://webmozarts.com/2013/06/19/the-power-of-uniform-resource-location-in-php/
- http://us3.php.net/manual/en/functions.anonymous.php
- http://en.wikipedia.org/wiki/Anonymous_function
- https://speakerdeck.com/cassell/obtaining-closure-with-anonymous-functions
- http://fabien.potencier.org/article/17/on-php-5-3-lambda-functions-and-closures
- Garfield, Larry. Interoperability: The Future of PHP, php[architect] Magazine November 2013, Volume 12 - Issue 11
- Tankersley, Chris. Composer.json for Fun and Profit, php[architect] Magazine August 2013 Volume 12 - Issue 8
- Thijssen, Joshua. Mastering the SPL Library. Musketeers.me, LLC. July 2013
The State of PHP
By Juan Manuel Torres
The State of PHP
- 1,942