За последние 24 часа нас посетил 21641 программист и 1390 роботов. Сейчас ищут 711 программистов ...

slim framework

Тема в разделе "PHP для профи", создана пользователем askanim, 30 мар 2017.

  1. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    Кто может плиз мне объяснить зачем нужен callback ?
    Для каких обстоятельств и зачем это нужно ?
    PHP:
    1. <?php
    2. use Psr\Http\Message\ServerRequestInterface;
    3. use Psr\Http\Message\ResponseInterface;
    4.  
    5. $app = new \Slim\App;
    6. $app->add(function (ServerRequestInterface $request, ResponseInterface $response, callable $next) {
    7.     // Use the PSR 7 $request object
    8.  
    9.     return $next($request, $response);
    10. });
    11. // Define app routes...
    12. $app->run();
     
  2. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.556
    Симпатии:
    1.755
    callable для того, чтобы можно было несколько правил навесить.
    А это нужно для гибкости и избегания повтора. Допустим, к одному роуту может обратится только неавторизованный пользователь, к другому - любой авторизованный, к третьему - авторизованный, и набравший 30 баллов в крестики-нолики :) Вот авторизацию выносишь в отдельный middleware, и не повторяешь её два раза, а на третий роут навешиваешь ещё проверку баллов пользователя
     
    askanim нравится это.
  3. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    это ж miidleware ) Тебе передается объект с запросом к серверу и ты на основе него можешь произвести некоторые действия с ответом. К примеру, проверить что все post-запросы должны быть сопровождены определенным токеном, или на все роуты начинающиеся с '/admin/' могут получить доступ лишь пользователи с определенными правами. Когда придет запрос все это выполнится в порядке добавления.
     
    askanim нравится это.
  4. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @mkramer суть понял не понял теперь как это в коде работает... Ужасные примеры в документации... Либо у меня ужасная не хватка знаний. Либо полное отсутствие понимания происходящего.
    --- Добавлено ---
    @romach @mkramer я думал для авторизации используются что - то типа этого
    PHP:
    1. $app->group('/users/{id:[0-9]+}', function () {
    2.         $this->map(['GET', 'DELETE', 'PATCH', 'PUT'], '', function ($request, $response, $args) {
    3.             // Find, delete, patch or replace user identified by $args['id']
    4.         })->setName('user');
    5.         $this->get('/reset-password', function ($request, $response, $args) {
    6.             // Route for /users/{id:[0-9]+}/reset-password
    7.             // Reset the password for user identified by $args['id']
    8.         })->setName('user-password-reset');
    9.     });
    Но я пока не понял как это работает сижу разбираюсь
    --- Добавлено ---
    @romach @mkramer вы не вкурсе какого нибудь живого рабочего примера на slim на гитхабе чтобы можно было посмотреть и потыкать...
     
  5. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.556
    Симпатии:
    1.755
    Группы используются, чтоб не повторять одно и тоже в каждом запросе. А middleware используется, чтоб навесить какие-то действия перед тем, как начнёт выполняться собственно роут, или сразу после того. На, посмотри, это я ради прикола как-то задачу Суриката на slim 3.0 решил (к тому же, хотелось попробовать третью версию, на реальных проектах только вторую использовал). У меня там используются и middleware в том числе, хотя можно было и больше их повесить https://github.com/mike-kramer/example
    --- Добавлено ---
    Я туда правда дамп базы не вывешивал, но там элементарная таблица.
    Код (Text):
    1.  
    2. CREATE TABLE `user` (
    3.  `id` int(11) NOT NULL AUTO_INCREMENT,
    4.  `login` varchar(100) NOT NULL,
    5.  `password` varchar(100) NOT NULL,
    6.  `birthday` date NOT NULL,
    7.  `counter` int(11) NOT NULL DEFAULT '0',
    8.  PRIMARY KEY (`id`)
    9. ) ENGINE=InnoDBDEFAULT CHARSET=utf8
     
    askanim нравится это.
  6. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @romach @mkramer ну разобрался) :D
    PHP:
    1. $app = new \Slim\App();
    2.  
    3.     $app->get('/', function ($request, $response) {
    4.         return $response->getBody()->write('Hello World');
    5.     });
    6.  
    7.     $app->group('/utils', function () use ($app) {
    8.         $this->get('/date', function ($request, $response) {
    9.             return $response->getBody()->write(date('Y-m-d H:i:s'));
    10.         });
    11.         $this->get('/time', function ($request, $response) {
    12.             return $response->getBody()->write(time());
    13.         });
    14.     })->add(function ($request, $response, $next) {
    15.         $response->getBody()->write('It is now ');
    16.         $response = $next($request, $response);
    17.         $response->getBody()->write('. Enjoy!');
    18.  
    19.         return $response;
    20.     });
    21.     $app->run();
     
  7. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @romach @mkramer Подскажите плиз как реализовать такую конструкцию... По данной логике слим ругается.
    PHP:
    1. $app->get('/', Controller\Auth\AuthController::class . ':register');
    2.  
    3.  
    4.     $app->group('/admin', function () use ($app) {
    5.  
    6.     })->add(function (Request $request, Response $response, $admin) use ($app) {
    7.         $app->get('/', Controller\Auth\AuthController::class . ':login'); // Нужно вызвать данный контроллер до проверки сессии.... При чём нужна ссылаться на /admin
    8. //но если вынести внешне ссылку, то да на неё заходит, то тогда не работает данная группа /admin :(
    9.         if(!isset($_SESSION['user_id'])) {
    10.  
    11.             return $response->withStatus(302)->withHeader('Location', '/');
    12.         }
    13.  
    14.         $response = $admin($request, $response);
    15.  
    16.         return $response;
    17.     });
    Прошу обратить внимание. На этот вызов контроллера. Его нужно вызвать до проверки сессии.
    PHP:
    1. $app->get('/', Controller\Auth\AuthController::class . ':login');
    Нужно вызвать данный контроллер до проверки сессии.... При чём нужна ссылаться на /admin
    Но если вынести внешне ссылку, то да на неё заходит и тогда не работает данная группа /admin :(
    --- Добавлено ---
    По какой логике заставить слим сделать то что я хочу?
     
  8. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
  9. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.556
    Симпатии:
    1.755
    Не совсем въезжаю, что ты пытаешься сделать, опиши без кода, но, ИМХО, тебе нужен не контроллер, а middleware свой написать
    --- Добавлено ---
    Ты не врубаешься. Эта строка не вызывает контроллер, она говорит, что при моршруте / надо вызывать метод логин экземпляра указанного класса. Посмотрел внимательно, тебе 100% надо организовать цепочку middleware. Они вызываются в том порядке, в котором добавлены.
     
    romach нравится это.
  10. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    Разобрался

    PHP:
    1. $app->get('/', Controller\Auth\AuthController::class . ':register');
    2.     $app->get('/admin[/]', Controller\Auth\AuthController::class . ':login');
    3.  
    4.  
    5.     $app->group('/admin', function () use ($app) {
    6.           // а здесь уже будут ваше заблокированные маршруты от внешних глаз) Если вы не индентифицированы по сессии)
    7.     })->add(function (Request $request, Response $response, $admin) {
    8.  
    9.         if(!isset($_SESSION['user_id'])) {
    10.  
    11.             return $response->withStatus(302)->withHeader('Location', '/');
    12.         }
    13.  
    14.         $response = $admin($request, $response);
    15.  
    16.         return $response;
    17.     });
    --- Добавлено ---
    @mkramer
    Что значит написать свой middleware а это что тогда ?
    PHP:
    1. $app->group('/admin', function () use ($app) {
    2.  
    3.     })->add(function (Request $request, Response $response, $admin) {
    4.  
    5.         if(!isset($_SESSION['user_id'])) {
    6.  
    7.             return $response->withStatus(302)->withHeader('Location', '/');
    8.         }
    9.  
    10.         $response = $admin($request, $response);
    11.  
    12.         return $response;
    13.     });
    который является контроллером у меня . вот прошу:
    PHP:
    1. <?php
    2. /**
    3. * Created by PhpStorm.
    4. * User: Леонид
    5. * Date: 04.04.2017
    6. * Time: 17:35
    7. */
    8.  
    9. namespace Admin\Controller\Auth;
    10.  
    11. use Psr\Container\ContainerInterface;
    12. class AuthController
    13. {
    14.     // constructor receives container instance
    15.     public function __construct(ContainerInterface $container) {
    16.  
    17.         $this->container = $container;
    18.     }
    19.     public function login ($request, $response, $args) {
    20.         $view = $this->container->get('view');
    21.  
    22.         $view->render($response, 'admin/auth/login.html', []);
    23.         return $response;
    24.     }
    25.     public function register($request, $response, $args) {
    26.         $view = $this->container->get('view');
    27.  
    28.         $view->render($response, 'admin/auth/register.html', []);
    29.         return $response;
    30.     }
    31. }
    --- Добавлено ---
    Если я делаю неправильно можешь пожалуйста рассказать что не так... ?
     
  11. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.556
    Симпатии:
    1.755
    Сейчас вроде похоже на правду.
     
  12. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @mkramer @romach Выкладываю свой контроллер и индекс, не могу понять что не так с csrf делаю... Не работает.
    Сначала индекс:
    PHP:
    1. <?php
    2.  
    3.     require 'vendor/autoload.php';
    4. /*
    5.     $config = new config\Config();*/
    6.     $app = new \Slim\App([
    7.         'settings' => [
    8.             'displayErrorDetails' => true,
    9.         ]
    10.     ]);
    11.     // Указываем необходимые параметры в контейнере
    12.     $container = $app->getContainer();
    13.     $container['view'] = function ($container) {
    14.         return new \Slim\Views\PhpRenderer(__DIR__ . '/Template');
    15.     };
    16.     // Занесём csrf в контейнер
    17.     $container['csrf'] = function ($c) {
    18.         return new \Slim\Csrf\Guard;
    19.     };
    20.     // Вставим файл с маршрутами
    21.     require_once __DIR__ . '/Admin/Router.php';
    22.  
    23.     //
    24.  
    25.  
    26.     session_start();
    27.     $app->run();
    Теперь контроллер:

    PHP:
    1. <?php
    2. /**
    3. * Created by PhpStorm.
    4. * User: Леонид
    5. * Date: 04.04.2017
    6. * Time: 17:35
    7. */
    8.  
    9. namespace Admin\Controller\Auth;
    10.  
    11. use \Psr\Http\Message\ServerRequestInterface as Request;
    12. use \Psr\Http\Message\ResponseInterface as Response;
    13. use Psr\Container\ContainerInterface;
    14.  
    15. class AuthController
    16. {
    17.     // constructor receives container instance
    18.     public function __construct(ContainerInterface $container) {
    19.         $this->container = $container;
    20.     }
    21.     public function login (Request $request, Response $response, $args) {
    22.         $view = $this->container->get('view');
    23.         $csrf = $this->container->get('csrf');
    24.         $nameKey = $csrf->getTokenNameKey();
    25.         $valueKey = $csrf->getTokenValueKey();
    26.         $name = $request->getAttribute($nameKey);
    27.         $value = $request->getAttribute($valueKey);
    28.  
    29.  
    30.         $view->render($response, 'admin/auth/login.html',[
    31.             'csrf'   => [
    32.                 'keys' => [
    33.                     'name'  => $nameKey,
    34.                     'value' => $valueKey
    35.                     ],
    36.                 'name'  => $name,
    37.                 'value' => $value
    38.             ]
    39.         ]
    40.         );
    41.         return $response;
    42.     }
    43.     public function register(Request $request, Response $response, $args) {
    44.         $view = $this->container->get('view');
    45.         $csrf = $this->container->get('csrf');
    46.         $nameKey = $csrf->getTokenNameKey();
    47.         $valueKey = $csrf->getTokenValueKey();
    48.         $name = $request->getAttribute($nameKey); // Эти значение почему то пусты :(
    49.         $value = $request->getAttribute($valueKey); // Эти значение почему то пусты :(
    50.  
    51.         $view->render($response, 'admin/auth/register.html', [
    52.             'csrf'   => [
    53.                 'keys' => [
    54.                     'name'  => $nameKey,
    55.                     'value' => $valueKey
    56.                 ],
    57.                 'name'  => $name,
    58.                 'value' => $value
    59.             ]
    60.         ]);
    61.         return $response;
    62.     }
    63. }
    --- Добавлено ---
    Кто нибудь помогите разобраться как правильно цифровую подпись реализовать то...
     
  13. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    PHP:
    1.  
    2. $app = new \Slim\App();
    3.  
    4. // Register with container
    5. $container = $app->getContainer();
    6. $container['csrf'] = function ($c) {
    7.     return new \Slim\Csrf\Guard;
    8. };
    9.  
    10. $app->get('/',function (Request $request,Response $response, $args) {
    11.     $nameKey = $this->csrf->getTokenNameKey();
    12.     $valueKey = $this->csrf->getTokenValueKey();
    13.     $name = $request->getAttribute($nameKey);
    14.     $value = $request->getAttribute($valueKey);
    15.  
    16.     $tokenArray = [
    17.         $nameKey => $name,
    18.         $valueKey => $value
    19.     ];
    20.     print_r($tokenArray);
    21.     return $response;
    22. })->add($container->get('csrf'));
    23.  
    24.  
    25.  
    26. $app->run();
    По такой схеме всё чудесно работает.... А вот по моей через контроллеры какая то фигня :///
     
  14. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    PHP:
    1. <?php
    2. /**
    3. * Created by PhpStorm.
    4. * User: Леонид
    5. * Date: 04.04.2017
    6. * Time: 17:35
    7. */
    8.  
    9. namespace Admin\Controller\Auth;
    10.  
    11. use \Psr\Http\Message\ServerRequestInterface as Request;
    12. use \Psr\Http\Message\ResponseInterface as Response;
    13. use Psr\Container\ContainerInterface;
    14.  
    15. class AuthController
    16. {
    17.     // constructor receives container instance
    18.     public function __construct(ContainerInterface $container) {
    19.         $this->csrf = new \Slim\Csrf\Guard();
    20.         $this->container = $container;
    21.     }
    22.     public function login (Request $request, Response $response, $args) {
    23.         $view = $this->container->get('view');
    24.         $nameKey = $this->csrf->getTokenNameKey();
    25.         $valueKey = $this->csrf->getTokenValueKey();
    26.         $token = $this->csrf->generateToken();
    27.  
    28.         $view->render($response, 'admin/auth/login.html',[
    29.             'csrf'   => [
    30.                 'keys' => [
    31.                     'name'  => $nameKey,
    32.                     'value' => $valueKey
    33.                 ],
    34.                 'name'  => $token[$nameKey],
    35.                 'value' => $token[$valueKey]
    36.             ]
    37.         ]
    38.         );
    39.         return $response;
    40.     }
    41.     public function register(Request $request, Response $response, $args) {
    42.         $view = $this->container->get('view');
    43.  
    44.  
    45.  
    46.         $nameKey = $this->csrf->getTokenNameKey();
    47.         $valueKey = $this->csrf->getTokenValueKey();
    48.         $token = $this->csrf->generateToken();
    49.  
    50.         $view->render($response, 'admin/auth/register.html', [
    51.             'csrf'   => [
    52.                 'keys' => [
    53.                     'name'  => $nameKey,
    54.                     'value' => $valueKey
    55.                 ],
    56.                 'name'  => $token[$nameKey],
    57.                 'value' => $token[$valueKey]
    58.             ]
    59.         ]);
    60.         return $response;
    61.     }
    62. }
    Сделал в контроллере не посредственный вызов guard... Токены генерируются... Теперь надо проверить их...
     
  15. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.556
    Симпатии:
    1.755
    Проверкой csrf занимается middleware. Даже если у тебя контроллеры, тебе их надо добавить в ручную к путям, насколько я понял из документации.
    --- Добавлено ---
    Или добавь его к приложению, чтоб все post-запросы через него проходили. В конце концов, зайди в код расширения, посмотри, как работает.
    --- Добавлено ---
    Вообще, читай доку, там же всё есть: https://github.com/slimphp/Slim-Csrf ссылку взял с официального сайта slimframework. Я на все твои вопросы в доке за 2-3 минуты нахожу ответ :)
     
    askanim нравится это.
  16. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @mkramer ну токены генерировать я научился... А вот вопрос в том как их потом проверить нашёл метод валидейт, но я не совсем понимаю с чем он их сверяет, потому что я предполагал: что он хранит генерируемые значения в сессиях, но я не угадал....
    --- Добавлено ---
    @mkramer я плохо перевариваю доку, не всё понимаю что написано... Английский у меня страдает.
     
  17. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.556
    Симпатии:
    1.755
    Когда крепишь middleware к приложению или роуту - всё проверяется само, без твоего участия (о чём опять же написано в документации). Если хочешь сам проверять - никуда не крепишь, и делаешь, как на гитхабе нарисовано .

    Английский для понимания доки не суперский нужен. Разговариваю я по-английски через "ээээмм, мммммм...,", но доку читаю свободно. Просто приучай себя. В принципе, в доке-то большей частью исключительно специальная лексика, это не Шекспира читать в оригинале
    --- Добавлено ---
    https://github.com/slimphp/Slim-Csrf#manual-usage - полностью ручной режим, тогда ничего никуда не крепишь
     
  18. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @mkramer у меня без контроллеров всё поулчилось. Как в доке указано, а когда я вызываю в контроллерах csrf он почему то не генерирует токены... Я в ручную и сделал, посмотри в последнем примере.
    --- Добавлено ---
    @mkramer попробовал как с помощью add для middleware так и с помощью container, нет результатов в контроллерах. Там есть какой то способ ещё для использования твига, но чё то я его не до конца понял как использовать. Ну и ладно ща если получится в ручную то отпишу как сделал.
     
  19. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.556
    Симпатии:
    1.755
    askanim нравится это.
  20. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @mkramer а ты получается вызываешь csrf и в middleware и для каждого контроллера ещё раз... Оо
    --- Добавлено ---
    @mkramer я не догадался так попробовать....
    --- Добавлено ---
    @mkramer вопрос такой а как middleware не по uri разделять ? Как просто сделать группу маршрутов не зависящих от uri
     
  21. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.556
    Симпатии:
    1.755
    Маршруты - это и есть uri :)
    --- Добавлено ---
    А, дошло, что ты имел в виду. Не знаю, честно говоря.
    --- Добавлено ---
    Почему? Я просто к обоим маршрутам - и post и get добавляю middleware. в случае с get он генерирует мне значения, которые я потом использую, а в случае с post - ещё и проверяет
     
  22. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.556
    Симпатии:
    1.755
    В самом slim такого пока нету - можешь предложить или реализовать :) Выкрутиться можно так, по идее:
    PHP:
    1. $routes = [
    2.     $app->get("route1", function (/*...*/) {}),
    3.     $app->get("route2", function (/* ...*/) {})
    4. ];
    5. array_walk($routes, function ($r) { $r->add(new MyCustomMiddleware()});
     
    askanim нравится это.
  23. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    @askanim возьми люмен:
    1. Большинство твоих хотелок там уже реализовано нативно и из коробки
    2. Есть русская дока
    3. При необходимости легко мигрировать на laravel
    4. По скорости он ни чем не уступает другим микро-фреймворкам
     
    askanim и mahmuzar нравится это.
  24. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @romach тут чуть чуть поздняк метаться я уже половину slim расковырял :D Как то обидно бросать на пол пути :)
    --- Добавлено ---
    @mkramer Оригинально :)
    --- Добавлено ---
    Давайте построим сообщество по micro framework slim :)
    1. сделаем для него сайт и русифицируем доку.
    2. Внедрим дополнения (новый функционал).
    3. Сделаем чат на gitter.
     
  25. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Зачем, когда есть русское сообщество по laravel/lumen? )