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 19

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.

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 鈥渃ontroller鈥, 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 ^^

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

He visto esta clase 3 veces, Ahora todo tiene sentido. 馃く
.
Luego de entender esto entiendo que Laravel no es magia negra ! 馃お
.

Any sufficiently advanced technology is indistinguishable from magic

.
Lo dijo : Arthur C. Clarke

En que momento define la varaible container?

No logro encontrar el detalle, me sale lo siguiente:
Fatal error: Uncaught Error: Class 鈥榃oohooLabs\Harmony\Middleware\HttpHandlerRunnerMiddleware鈥 not found in /var/www/html/curso-php-platzi/public/index.php on line 110
( ! ) Error: Class 鈥榃oohooLabs\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 鈥榓ction鈥? 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.