PSR
Чуть больше, чем стиль оформления кода
Анатолий Притульский
PHP-developer at Travellizy
Ссылка на слайды
2/72
Про стандарты
3/72
USB
4/72
Стандарты в PHP
5/72
PSR
PHP Standards Recommendations
6/72
Оформление кода
7/72
Code MUST use 4 spaces for indenting, not tabs.
8/72
PSR
Чуть больше, чем стиль оформления кода
9/72
10/72
Первый стандарт принят в 2010 году
12/72
Участники PHP-FIG
Composer, Zend Framework, Yii framework, CakePHP, Slim, PHPixie, Joomla, Magento, Drupal, phpDocumentor и др.
https://www.php-fig.org/personnel/
13/72
Бывшие участники PHP-FIG
Symfony, Laravel, Guzzle, Doctrine, Propel и др.
https://www.php-fig.org/personnel/
14/72
Почему покидают PHP-FIG?
15/72
PHP-FIG обсуждают новый стандарт
16/72
Стандарты
Это - полезно!
17/72
18/72
PSR-1 / PSR-2 / PSR-12
Basic Coding Standard
Coding Style Guide
Extended Coding Style Guide
19/72
PSR-1 / PSR-2 / PSR-12
PhpStorm Reformat Code
20/72
PSR-1 / PSR-2 / PSR-12
21/72
PSR-3
Logger Interface
22/72
PSR-3
Logger Interface
23/72
<?php
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());
}
24/72
PSR-3
Нет поддержки PSR-3?
25/72
26/72
PSR-0 / PSR-4
Autoloading Standard
27/72
PSR-0 / PSR-4
Оо ???
28/72
class MyLib {
private $CI;
public function __construct()
{
$this->CI = &get_instance();
$this->CI->load->library('encrypt');
$this->CI->load->library('session');
$this->CI->load->library('url');
$this->CI->load->helper('captcha');
$this->CI->load->helper('cookie');
$this->CI->load->helper('email');
}
...
}
PSR-0
deprecated с 2014 года
29/72
function autoload($className)
{
$className = ltrim($className, '\\');
$fileName = '';
$namespace = '';
if ($lastNsPos = strrpos($className, '\\')) {
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
$fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
require $fileName;
}
spl_autoload_register('autoload');
30/72
PSR-4
Composer Autoloading
31/72
"autoload": {
"psr-4": {
"Acme\\": "src/"
}
}
}
PSR-6 / PSR-16
Caching Interface
Simple Caching Interface
32/72
PSR-16
Simple Caching Interface
33/72
<?php
interface CacheInterface
{
public function get($key, $default = null);
public function set($key, $value, $ttl = null);
public function delete($key);
public function clear();
public function getMultiple($keys, $default = null);
public function setMultiple($values, $ttl = null);
public function deleteMultiple($keys);
public function has($key);
}
PSR-6
Caching Interface
34/72
35/72
36/72
PSR-7
HTTP Message Interface
37/72
PSR-7
Zend Diactoros
PSR-7 HTTP message implementations
38/72
39/72
40/72
PSR-11
Container Interface
41/72
PSR-11
Container Interface
42/72
<?php
interface ContainerInterface
{
public function get($id);
public function has($id);
}
43/72
PSR-11
44/72
<?php
class HomePageHandlerFactory
{
public function __invoke(ContainerInterface $container): RequestHandlerInterface
{
$router = $container->get(RouterInterface::class);
$template = $container->has(TemplateRendererInterface::class)
? $container->get(TemplateRendererInterface::class)
: null;
return new HomePageHandler(get_class($container), $router, $template);
}
}
45/72
46/72
PSR-13
Hypermedia Links
47/72
PSR-13
Общий способ представления
hypermedia links
48/72
PSR-13
Пример реализации
49/72
PSR-13
Hypermedia
то без чего ваше API не совсем REST
50/72
PSR-14
Event Dispatcher
51/72
PSR-14
52/72
namespace Psr\EventDispatcher;
interface EventDispatcherInterface
{
public function dispatch(object $event);
}
namespace Psr\EventDispatcher;
interface ListenerProviderInterface
{
public function getListenersForEvent(object $event) : iterable;
}
namespace Psr\EventDispatcher;
interface StoppableEventInterface
{
public function isPropagationStopped() : bool;
}
53/72
PSR-14
Symfony leaves PHP-FIG
https://medium.com/@tdutrion/symfony-and-psr-14-event-dispatcher-f5a9db6740e7
54/72
55/72
PSR-15
HTTP Handlers
56/72
PSR-15
Symfony Controller
57/72
<?php
class DefaultController extends AbstractController
{
/**
* @Route("/", name="homepage")
*/
public function index(): Response
{
$posts = $this->getDoctrine()->getRepository(Post::class)->findLatest();
return $this->render('default/index.html.twig', [
'posts' => $posts,
]);
}
}
PSR-15
Symfony Controller
58/72
<?php
class DefaultController extends AbstractController
{
public function list(): Response
{}
public function update(): Response
{}
public function create(): Response
{}
public function delete(): Response
{}
}
PSR-15
Goodbye Controllers,
hello request handlers
https://jenssegers.com/85/goodbye-controllers-hello-request-handlers
59/72
PSR-15
Request Handler
60/72
<?php
class CreateUserHandler
{
public function __construct(UserRepository $repository, Twig $twig)
{
// ...
}
public function __invoke(Request $request): Response
{
// ...
}
}
PSR-15
Request Handler
61/72
<?php
interface RequestHandlerInterface
{
public function handle(ServerRequestInterface $request): ResponseInterface;
}
<?php
interface MiddlewareInterface
{
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface;
}
PSR-15
Zend Expressive Handler
62/72
<?php
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ServerRequestInterface;
class PingHandler implements RequestHandlerInterface
{
public function handle(ServerRequestInterface $request): ResponseInterface
{
return new JsonResponse(['ack' => time()]);
}
}
PSR-17
HTTP Factories
63/72
PSR-17
Создать Request
64/72
<?php
use Psr\Http\Message\UriInterface;
use Psr\Http\Message\RequestInterface;
interface RequestFactoryInterface
{
public function createRequest(string $method, $uri): RequestInterface;
}
PSR-17
Создать Response
65/72
<?php
use Psr\Http\Message\ResponseInterface;
interface ResponseFactoryInterface
{
public function createResponse(
int $code = 200,
string $reasonPhrase = ''
): ResponseInterface;
}
PSR-18
HTTP Client
66/72
PSR-18
HTTP Client
67/72
<?php
interface ClientInterface
{
public function sendRequest(RequestInterface $request): ResponseInterface;
}
68/72
69/72
PSR
рекомендации
(а не жесткие правила)
70/72
71/72
Абстракции не должны зависеть от деталей.
Детали должны зависеть от абстракций.
72/72