Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Do you speak PSRs?

Do you speak PSRs?

Meetup PHPRS Serra Gaúcha (Canela)

Avatar for Eduardo de Brito Colombo

Eduardo de Brito Colombo

November 26, 2016
Tweet

More Decks by Eduardo de Brito Colombo

Other Decks in Programming

Transcript

  1. The group was bootstrapped by a number of framework developers

    at php|tek, Chicago, in 2009. Since then various other members have applied and been voted in, increasing the size of the group from the first 5 to over 20. PHP-FIG
  2. Aims of the PHP-FIG The idea behind the group is

    for project representatives to talk about the commonalities between our projects and find ways we can work together.
  3. RFC 2119 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",

    "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
  4. PSR-4: Autoloader This PSR describes a specification for autoloading classes

    from file paths. It is fully interoperable, and can be used in addition to any other autoloading specification, including PSR-0. This PSR also describes where to place files that will be autoloaded according to the specification.
  5. PSR-4: Autoloader The term "class" refers to classes, interfaces, traits,

    and other similar structures. A fully qualified class name has the following form: \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
  6. PSR-4: Autoloader • The fully qualified class name MUST have

    a top-level namespace name, also known as a "vendor namespace". • The fully qualified class name MAY have one or more sub-namespace names. • The fully qualified class name MUST have a terminating class name. • Underscores have no special meaning in any portion of the fully qualified class name. • Alphabetic characters in the fully qualified class name MAY be any combination of lower case and upper case. • All class names MUST be referenced in a case-sensitive fashion.
  7. PSR-4: Autoloader • When loading a file that corresponds to

    a fully qualified class name ... ◦ A contiguous series of one or more leading namespace and sub-namespace names, not including the leading namespace separator, in the fully qualified class name (a "namespace prefix") corresponds to at least one "base directory". ◦ The contiguous sub-namespace names after the "namespace prefix" correspond to a subdirectory within a "base directory", in which the namespace separators represent directory separators. The subdirectory name MUST match the case of the sub-namespace names. ◦ The terminating class name corresponds to a file name ending in .php. The file name MUST match the case of the terminating class name. ◦ \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName> • Autoloader implementations MUST NOT throw exceptions, MUST NOT
  8. PSR-4: Closure Example spl_autoload_register(function ($class) { $prefix = 'Foo\\Bar\\'; $base_dir

    = __DIR__ . '/src/'; $len = strlen($prefix); if (strncmp($prefix, $class, $len) !== 0) { return; } $relative_class = substr($class, $len); $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; if (file_exists($file)) { require $file; } });
  9. PSR-4: Class Example namespace Example; class Psr4AutoloaderClass { protected $prefixes

    = array(); public function register() { spl_autoload_register(array($this, 'loadClass')); } public function addNamespace($prefix, $base_dir, $prepend = false) ... public function loadClass($class) ... protected function loadMappedFile($prefix, $relative_class) ... protected function requireFile($file) … }
  10. PSR-1 (Coding styles) This section of the standard comprises what

    should be considered the standard coding elements that are required to ensure a high level of technical interoperability between shared PHP code.
  11. PSR-1 (Coding styles) • Files MUST use only <?php and

    <?= tags. • Files MUST use only UTF-8 without BOM (byte order marks ) for PHP code. • Files SHOULD either declare symbols (classes, functions, constants, etc.) or cause side-effects (e.g. generate output, change .ini settings, etc.) but SHOULD NOT do both. • Namespaces and classes MUST follow an "autoloading" PSR: [PSR-0, PSR-4]. • Class names MUST be declared in StudlyCaps. • Class constants MUST be declared in all upper case with underscore separators. • Method names MUST be declared in camelCase.
  12. PSR-1 (Coding styles) • Files MUST use only <?php and

    <?= tags. <?php //YOURCODE ?> <?= //YOURCODE ?> It MUST NOT use the other tag variations.
  13. PSR-1 (Coding styles) • Files SHOULD either declare symbols (classes,

    functions, constants, etc.) or cause side-effects (e.g. generate output, change .ini settings, etc.) but SHOULD NOT do both.
  14. PSR-1 (Coding styles) - Side effects (avoid) <?php // side

    effect: change ini settings ini_set('error_reporting', E_ALL); // side effect: loads a file include "file.php"; // side effect: generates output echo "<html>\n"; // declaration function foo() { // function body }
  15. PSR-1 (Coding styles) - Without side effects <?php // declaration

    function foo() { // function body } // conditional declaration is *not* a side effect if (! function_exists('bar')) { function bar() { // function body } }
  16. PSR-1 (Coding styles) • Namespaces and classes MUST follow an

    "autoloading" PSR: [PSR-0, PSR-4]. <?php // PHP 5.3 and later: namespace Vendor\Model; class Foo { }
  17. PSR-1 (Coding styles) • Code written for 5.2.x and before

    SHOULD use the pseudo-namespacing convention of Vendor_ prefixes on class names. <?php // PHP 5.2.x and earlier: class Vendor_Model_Foo { }
  18. PSR-1 (Coding styles) - Constants • Class constants MUST be

    declared in all upper case with underscore separators. <?php namespace Vendor\Model; class Foo { const VERSION = '1.0'; const DATE_APPROVED = '2012-06-01'; }
  19. PSR-1 (Coding styles) - Properties This guide intentionally avoids any

    recommendation regarding the use of $StudlyCaps, $camelCase, or $under_score property names. Whatever naming convention is used SHOULD be applied consistently within a reasonable scope. That scope may be vendor-level, package-level, class-level, or method-level.
  20. PSR-1 (Coding styles) - Methods • Method names MUST be

    declared in camelCase(). <?php ... public myFizzBuzz() { … } ...
  21. PSR-2: Coding Style Guide This guide extends and expands on

    PSR-1, the basic coding standard. The intent of this guide is to reduce cognitive friction when scanning code from different authors. It does so by enumerating a shared set of rules and expectations about how to format PHP code. The style rules herein are derived from commonalities among the various member projects. When various authors collaborate across multiple projects, it helps to have one set of guidelines to be used among all those projects. Thus, the benefit of this guide is not in the rules themselves, but in the sharing of those rules.
  22. PSR-2: Coding Style Guide • Code MUST follow a "coding

    style guide" PSR [PSR-1]. • Code MUST use 4 spaces for indenting, not tabs. • There MUST NOT be a hard limit on line length; the soft limit MUST be 120 characters; lines SHOULD be 80 characters or less. • There MUST be one blank line after the namespace declaration, and there MUST be one blank line after the block of use declarations. • Opening braces for classes MUST go on the next line, and closing braces MUST go on the next line after the body.
  23. PSR-2: Coding Style Guide • Visibility MUST be declared on

    all properties and methods; abstract and final MUST be declared before the visibility; static MUST be declared after the visibility. • Control structure keywords MUST have one space after them; method and function calls MUST NOT. • Opening braces for control structures MUST go on the same line, and closing braces MUST go on the next line after the body. • Opening parentheses for control structures MUST NOT have a space after them, and closing parentheses for control structures MUST NOT have a space before.
  24. PSR-3: Logger Interface This document describes a common interface for

    logging libraries. The main goal is to allow libraries to receive a Psr\Log\LoggerInterface object and write logs to it in a simple and universal way. Frameworks and CMSs that have custom needs MAY extend the interface for their own purpose, but SHOULD remain compatible with this document. This ensures that the third-party libraries an application uses can write to the centralized application logs.
  25. PSR-3: Logger Interface 1. Specification 1.1. Basics (RFC 5424) 1.2.

    Message 1.3. Context 1.4. Helper classes and interfaces 2. Package (psr/log) 3. Psr\Log\LoggerInterface 4. Psr\Log\LoggerAwareInterface 5. Psr\Log\LogLevel
  26. PSR-3: Psr\Log\LoggerInterface namespace Psr\Log; interface LoggerInterface { public function emergency($message,

    array $context = array()); public function alert($message, array $context = array()); public function critical($message, array $context = array()); public function error($message, array $context = array()); public function warning($message, array $context = array()); public function notice($message, array $context = array()); public function info($message, array $context = array()); public function debug($message, array $context = array()); public function log($level, $message, array $context = array()); }
  27. PSR-3: Psr\Log\LogLevel class LogLevel { const EMERGENCY = 'emergency'; const

    ALERT = 'alert'; const CRITICAL = 'critical'; const ERROR = 'error'; const WARNING = 'warning'; const NOTICE = 'notice'; const INFO = 'info'; const DEBUG = 'debug'; }
  28. PSR-6: Caching Interface Caching is a common way to improve

    the performance of any project, making caching libraries one of the most common features of many frameworks and libraries. This has lead to a situation where many libraries roll their own caching libraries, with various levels of functionality. These differences are causing developers to have to learn multiple systems which may or may not provide the functionality they need. In addition, the developers of caching libraries themselves face a choice between only supporting a limited number of frameworks or creating a large number of adapter classes. A common interface for caching systems will solve these problems. Library and framework developers can count on the caching systems working the way they're expecting, while the developers of caching systems will only have to implement a single set of interfaces rather than a whole assortment of adapters.
  29. PSR-6: Caching Interface The goal of this PSR is to

    allow developers to create cache-aware libraries that can be integrated into existing frameworks and systems without the need for custom development.
  30. PSR-6: Caching Interface • Definitions ◦ Calling Library ◦ Implementing

    Library ◦ TTL ◦ Expiration ◦ Key ◦ Hit ◦ Miss ◦ Deferred
  31. PSR-6: Caching Interface Data: Implementing libraries MUST support all serializable

    PHP data types, including: • Strings - Character strings of arbitrary size in any PHP-compatible encoding. • Integers - All integers of any size supported by PHP, up to 64-bit signed. • Floats - All signed floating point values. • Boolean - True and False. • Null - The actual null value. • Arrays - Indexed, associative and multidimensional arrays of arbitrary depth. • Object - Any object that supports lossless serialization and deserialization.
  32. PSR-6: Caching Interface Key Concepts • Pool The Pool represents

    a collection of items in a caching system. The pool is a logical Repository of all items it contains. All cacheable items are retrieved from the Pool as an Item object, and all interaction with the whole universe of cached objects happens through the Pool. • Items An Item represents a single key/value pair within a Pool. The key is the primary unique identifier for an Item and MUST be immutable. The Value MAY be changed at any time.
  33. PSR-6: Caching Interface interface CacheItemInterface { public function getKey(); public

    function get(); public function isHit(); public function set($value); public function expiresAt($expiration); public function expiresAfter($time); }
  34. PSR-6: Caching Interface interface CacheItemPoolInterface { public function getItem($key); public

    function getItems(array $keys = array()); public function hasItem($key); public function clear(); public function deleteItem($key); public function deleteItems(array $keys); public function save(CacheItemInterface $item); public function saveDeferred(CacheItemInterface $item); public function commit();
  35. PSR-6: Caching Interface namespace Psr\Cache; /** * Exception interface for

    all exceptions thrown by an Implementing Library. */ interface CacheException { }
  36. PSR-6: Caching Interface namespace Psr\Cache; /** * Exception interface for

    invalid cache arguments. * * Any time an invalid argument is passed into a method it must throw an * exception class which implements Psr\Cache\InvalidArgumentException. */ interface InvalidArgumentException extends CacheException { }
  37. PSR-7: HTTP message interfaces This document describes common interfaces for

    representing HTTP messages as described in RFC 7230 and RFC 7231, and URIs for use with HTTP messages as described in RFC 3986.
  38. PSR-7: HTTP message interfaces Specification Messages • Psr\Http\Message\RequestInterface • Psr\Http\Message\ResponseInterface

    • Psr\Http\Message\MessageInterface Both RequestInterface and ResponseInterface extend MessageInterface
  39. PSR-7: HTTP message interfaces HTTP Headers • Case-insensitive header field

    names $message = $message->withHeader('fOO', 'baz'); echo $message->getHeaderLine('foo'); // Outputs: baz
  40. PSR-7: HTTP message interfaces HTTP Headers • Headers with multiple

    values $message = $message ->withHeader('foo', 'bar') ->withAddedHeader('foo', 'baz'); $header = $message->getHeaderLine('foo'); // $header contains: 'bar, baz'
  41. PSR-7: HTTP message interfaces HTTP Headers • Host header In

    requests, the Host header typically mirrors the host component of the URI, as well as the host used when establishing the TCP connection. However, the HTTP specification allows the Host header to differ from each of the two. This table illustrates what getHeaderLine('Host') will return for a request returned by withUri() with the $preserveHost argument set to true for various initial requests and URIs.
  42. public function getProtocolVersion(); public function withProtocolVersion($version); public function getHeaders(); public

    function hasHeader($name); public function getHeader($name); public function getHeaderLine($name); public function withHeader($name, $value); public function withAddedHeader($name, $value); public function withoutHeader($name); public function getBody(); public function withBody(StreamInterface $body); PSR-7: interface MessageInterface
  43. interface RequestInterface extends MessageInterface public function getRequestTarget(); public function withRequestTarget($requestTarget);

    public function getMethod(); public function withMethod($method); public function getUri(); public function withUri(UriInterface $uri, $preserveHost = false); } PSR-7: RequestInterface extends MessageInterface
  44. public function getServerParams(); public function getCookieParams(); public function withCookieParams(array $cookies);

    public function getQueryParams(); public function withQueryParams(array $query); public function getUploadedFiles(); public function withUploadedFiles(array $uploadedFiles); public function getParsedBody(); public function withParsedBody($data); public function getAttributes(); public function getAttribute($name, $default = null); public function withAttribute($name, $value); public function withoutAttribute($name); PSR-7: interface ServerRequestInterface extends RequestInterface
  45. interface ResponseInterface extends MessageInterface { public function getStatusCode(); public function

    withStatus($code, $reasonPhrase = ''); public function getReasonPhrase(); } PSR-7: interface ResponseInterface extends MessageInterface
  46. public function __toString(); public function close(); public function detach(); public

    function getSize(); public function tell(); public function eof(); public function isSeekable(); public function seek($offset, $whence = SEEK_SET); public function rewind(); public function isWritable(); public function write($string); public function isReadable(); public function read($length); public function getContents(); public function getMetadata($key = null); PSR-7: interface StreamInterface
  47. PSR-13: Link definition interfaces Hypermedia links are becoming an increasingly

    important part of the web, in both HTML contexts and various API format contexts. However, there is no single common hypermedia format, nor is there a common way to represent Links between formats. This specification aims to provide PHP developers with a simple, common way of representing a hypermedia link independently of the serialization format that is used. That in turn allows a system to serialize a response with hypermedia links into one or more wire formats independently of the process of deciding what those links should be.
  48. PSR-13: Link definition interfaces References RFC 2119 RFC 4287 RFC

    5988 RFC 6570 IANA Link Relations Registry Microformats Relations List
  49. PSR-13: Link definition interfaces For the purposes of this specification,

    the following definitions apply. • Implementing Object -An object that implements one of the interfaces defined by this specification. • Serializer - A library or other system that takes one or more Link objects and produces a serialized representation of it in some defined format.
  50. PSR-13: Link definition interfaces For the purposes of this specification,

    the following definitions apply. • Implementing Object -An object that implements one of the interfaces defined by this specification. • Serializer - A library or other system that takes one or more Link objects and produces a serialized representation of it in some defined format. All links MAY include zero or more additional attributes beyond the URI and relationship.
  51. PSR-13: Link definition interfaces Link relationships are defined as strings,

    and are either a simple keyword in case of a publicly defined relationship or an absolute URI in the case of a private relationships. In case a simple keyword is used, it SHOULD match one from the IANA registry at: http://www.iana.org/assignments/link-relations/link-relations.xhtml Optionally the microformats.org registry MAY be used, but this may not be valid in every context: http://microformats.org/wiki/existing-rel-values A relationship that is not defined in one of the above registries or a similar public registry is considered "private", that is, specific to a particular application or use case. Such relationships MUST use an absolute URI.
  52. PSR-13: Link definition interfaces Link Templates RFC 6570 defines a

    format for URI templates, that is, a pattern for a URI that is expected to be filled in with values provided by a client tool. Some hypermedia formats support templated links while others do not, and may have a special way to denote that a link is a template. A Serializer for a format that does not support URI Templates MUST ignore any templated Links it encounters.
  53. PSR-13: Link definition interfaces namespace Psr\Link; interface LinkInterface { public

    function getHref(); public function isTemplated(); public function getRels(); public function getAttributes(); }
  54. PSR-11: Container interfaces (Review) • This document describes a common

    interface for dependency injection containers. • The goal set by ContainerInterface is to standardize how frameworks and libraries make use of a container to obtain objects and parameters (called entries in the rest of this document).