No tienes acceso a esta clase

¬°Contin√ļa aprendiendo! √önete y comienza a potenciar tu carrera

Curso Avanzado de PHP

Curso Avanzado de PHP

Héctor Benitez

Héctor Benitez

Implementando el server request handler

17/35
Recursos
  • Debes acostumbrarte a leer c√≥digo de otras personas o librer√≠as. Detr√°s de todo hay un programador haciendo algo que podr√°s entender y modificar.
  • Es muy importante que leas los errores ya que muchas veces te dar√° pistas muy buenas de lo que est√° sucediendo.

Aportes 18

Preguntas 2

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Es un poco complicado y seguir este video, varias cosas ya estàn deprecadas y se hace muy tedioso la instalaciòn de dependencias de las dependencias.

Utilizar harmony simplifica realmente las cosas

Para los que tengan un error con el SapiEmitter de zend lo que deben hacer es desinstalarlo
composer remove zendframework/zend-httphandlerrunner
Y luego instalar el de laminas
composer require laminas/laminas-httphandlerrunner

Siento que todo se enredo mucho, creo que era mejor utilizar el fast-router.
Aunque estuvo muy buena la clase de ejemplo de como depurar el codigo

En que momento define la varaible container?

Interesante, trataré de explicar un poco mejor qué sucedió, la clase DispatcherMiddleware en su método process hace uso de $request, recordemos que nosotros le pasamos este $request en el constructor de Harmony en nuestro index,php, y precisamente ese $request lo maneja Zend (Laminas ahora), entonces, cuando Harmony manda a llamar a process le inyecta ese mismo $request.

Entonces, debido a la convenci√≥n psr-7, Harmony sabe que si o si $request va a tener llamado un m√©todo llamado getAttribute(), esto porque el objeto request trae en sus propiedades una lista de atributos, y estos atributos son a√Īadidos por nuestro router, y esos atributos son los mismos que nosotros espec√≠ficamos, y getAttribute() es simplemente un getter.

Si miramos más abajo en el código de process, vemos que está la condicional is_array($action) && is_string($action[0]) && is_string($action[1])

Bueno, esta condicion lo que hace es verificar que $action sea un array, y si recuerdas, $action viene de nuestro getAttribute(), por lo que $action va a ser el array que nosotros pasamos en nuestras rutas (Esto por lo que ya te expliqué arriba)

Entonces, pregunta por $action[0], nosotros inicialmente ten√≠amos definido un arreglo con indices asociativos, y al primer indice lo llamamos ‚Äúcontroller‚ÄĚ, por tanto, cuando Harmony trata de buscar el √≠ndice 0 se da cuenta que no existe y manda un error, es por eso que borramos los indices, porque de esa manera PHP al no ver un √≠ndice, pone por defecto al √≠ndice 0 y as√≠ sucesivamente (Como cualquier lenguaje de programaci√≥n)

Y gracias a las convenciones PSR Harmony sabe que tu a través del índice 0 vas a pasar un controlador y a través del índice 1 tu vas a pasar un método.

Y el error de Jobs fue porque nuestra clase Jobs espera que le inyectemos una dependencia, y eso lo haciamos antes manualmente usando un contenedor que hacía ese trabajo por nosotros, pero ahora estamos usando Harmony, y Harmony se encarga de eso ahora, por lo que debemos indicarle a Harmony qué contenedor de inyección de dependencias debe usar, es por eso que le pasamos ese $container, que si recuerdas más arriba en el código, $container es una instancia de DI\Container y DI (Dependencu Injection) es el paquete que manejamos para inyección de dependencias ^^

No logro encontrar el detalle, me sale lo siguiente:
Fatal error: Uncaught Error: Class ‚ÄėWoohooLabs\Harmony\Middleware\HttpHandlerRunnerMiddleware‚Äô not found in /var/www/html/curso-php-platzi/public/index.php on line 110
( ! ) Error: Class ‚ÄėWoohooLabs\Harmony\Middleware\HttpHandlerRunnerMiddleware‚Äô not found in /var/www/html/curso-php-platzi/public/index.php on line 110
Call Stack

<h1>Time Memory Function Location</h1>
1 0.0002 382472 {main}( ) …/index.php:0

<code>
<?php
require_once '../vendor/autoload.php';

session_start();

$dotenv = Dotenv\Dotenv::create(__DIR__ . '/..');
$dotenv->load();

use Illuminate\Database\Capsule\Manager as Capsule;
use Aura\Router\RouterContainer;
use WoohooLabs\Harmony\Harmony;
use WoohooLabs\Harmony\Middleware\DispatcherMiddleware;
use WoohooLabs\Harmony\Middleware\HttpHandlerRunnerMiddleware;
use Zend\Diactoros\Response;
use Zend\HttpHandlerRunner\Emitter\SapiEmitter;

$container = new DI\Container();

$capsule = new Capsule;

$capsule->addConnection([
    'driver'    => 'mysql',
    'host'      => getenv('DB_HOST'),
    'database'  => getenv('DB_NAME'),
    'username'  => getenv('DB_USER'),
    'password'  => getenv('DB_PASS'),
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
]);
$capsule->setAsGlobal();
$capsule->bootEloquent();

$request = Zend\Diactoros\ServerRequestFactory::fromGlobals(
  $_SERVER,
  $_GET,
  $_POST,
  $_COOKIE,
  $_FILES
);

$routerContainer = new RouterContainer();
$map = $routerContainer->getMap();

$map->get('index', '/curso-php-platzi/', [
    'controller' => 'App\Controllers\IndexController',
    'action' => 'indexAction'
]);

$map->get('indexJobs', '/curso-php-platzi/jobs', [
    'controller' => 'App\Controllers\JobsController',
    'action' => 'indexAction'
]);
$map->get('deleteJobs', '/curso-php-platzi/jobs/delete', [
    'controller' => 'App\Controllers\JobsController',
    'action' => 'deleteAction'
]);

$map->get('addJobs', '/curso-php-platzi/jobs/add', [
    'controller' => 'App\Controllers\JobsController',
    'action' => 'getAddJobAction'
]);

$map->post('saveJobs', '/curso-php-platzi/jobs/add', [
    'controller' => 'App\Controllers\JobsController',
    'action' => 'getAddJobAction'
]);

$map->get('addUsers', '/curso-php-platzi/users/add', [
    'controller' => 'App\Controllers\UsersController',
    'action' => 'getAddUserAction'
]);

$map->post('saveUsers', '/curso-php-platzi/users/add', [
    'controller' => 'App\Controllers\UsersController',
    'action' => 'getAddUserAction'
]);

$map->get('loginForm', '/curso-php-platzi/login', [
    'controller' => 'App\Controllers\AuthController',
    'action' => 'getLogin'
]);

$map->get('logout', '/curso-php-platzi/logout', [
    'controller' => 'App\Controllers\AuthController',
    'action' => 'getLogout',
]);

$map->post('auth', '/curso-php-platzi/auth', [
    'controller' => 'App\Controllers\AuthController',
    'action' => 'postLogin'
]);

$map->get('admin', '/curso-php-platzi/admin', [
    'controller' => 'App\Controllers\AdminController',
    'action' => 'getIndex',
    'auth' => true
]);


$matcher = $routerContainer->getMatcher();
$route = $matcher->match($request);

if (!$route) {
    echo 'No route';
}else{
    $harmony = new Harmony($request, new Response());
    $harmony
        ->addMiddleware(new HttpHandlerRunnerMiddleware(new SapiEmitter()))
        ->addMiddleware(new Middlewares\AuraRouter($routerContainer))
        ->addMiddleware(new AuthenticationMiddleware())
        ->addMiddleware(new DispatcherMiddleware($container, 'request-handler'));
    $harmony();
}

Alguien? no puedo avanzar con el curso debido a mi error, alguien me puede ayudar?

Y si en vez de usar un arreglo para definir el controlador y la acción usas closure, como se hace para que el Container pueda inyectar?.

Fatal error: Uncaught Zend\HttpHandlerRunner\Exception\EmitterException: Output has been emitted previously; cannot emit response in C:\xampp\htdocs\curso-php\vendor\zendframework\zend-httphandlerrunner\src\Exception\EmitterException.php:23 Stack trace: #0 C:\xampp\htdocs\curso-php\vendor\zendframework\zend-httphandlerrunner\src\Emitter\SapiEmitterTrait.php(39): Zend\HttpHandlerRunner\Exception\EmitterException::forOutputSent() #1 C:\xampp\htdocs\curso-php\vendor\zendframework\zend-httphandlerrunner\src\Emitter\SapiEmitter.php(26): Zend\HttpHandlerRunner\Emitter\SapiEmitter->assertNoPreviousOutput() #2 C:\xampp\htdocs\curso-php\vendor\woohoolabs\harmony\src\Middleware\HttpHandlerRunnerMiddleware.php(36): Zend\HttpHandlerRunner\Emitter\SapiEmitter->emit(Object(Zend\Diactoros\Response\HtmlResponse)) #3 C:\xampp\htdocs\curso-php\vendor\woohoolabs\harmony\src\Harmony.php(128): WoohooLabs\Harmony\Middleware\HttpHandlerRunnerMiddleware->process(Object(Zend\Diactoros\ServerRequest), Object(WoohooLabs\Harmony\Harmony)) #4 C:\xamp in C:\xampp\htdocs\curso-php\vendor\zendframework\zend-httphandlerrunner\src\Exception\EmitterException.php on line 23

Tuve un error en el aura-router y para arreglarlo lo cambie por el que recomendaba harmony

Y si quiero utilizar 2 o mas funciones dentro de mi Controller, como deberia hacer? Como seria el ‚Äėaction‚Äô? Porque siempre utiliza una funcion en cada Controller.

Debes acostumbrarte a leer código de otras personas o librerías. Detrás de todo hay un programador haciendo algo que podrás entender y modificar.

Es muy importante que leas los errores ya que muchas veces te dar√° pistas muy buenas de lo que est√° sucediendo.

Debes acostumbrarte a leer código de otras personas o librerías. Detrás de todo hay un programador haciendo algo que podrás entender y modificar

Es muy importante que leas los errores ya que muchas veces te dar√° pistas muy buenas de lo que est√° sucediendo

Para la prueba, no he implementado el response con Twig, por lo que me arrojaba un Fatal error indicando que debía ser un return de tipo Interface, por lo que he utilizado el ejemplo básico de FastRouteMiddleware en AuraRouter para el controlador, de la siguiente manera:

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

public function indexAction(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
	$users = [
		"Steve",
		"Arnie",
		$this->jobService->getJobs()['user']
	];

	$response->getBody()->write(json_encode($users));

	return $response;
}```

Y que hay con la autenticación, seguro ahora lo crearemos un middleware para el auth y las rutas protegidas.