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.
Introducción
PHP: qué aprenderás en este curso
Herramientas
IDEs
Virtualización con Vagrant
Configuración de virtual host
Características avanzadas del lenguaje
Closures
Type Hinting
Agregar imágenes en Jobs
Salvar imágenes en Jobs
Traits
Endpoint to delete Jobs
Third party Traits - Soft Delete
Técnicas de programación
SOLID
SOLID a profundidad
Inyección de dependencias
Contenedor de inyección de dependencias
Middlewares y PSR15
Implementando el server request handler
Creando un middleware
Errores y debug
Error Handling
La biblioteca SPL
Debug
Xdebug
Logs
Trabajando con Monolog
Databases
Migraciones de bases de datos
Comandos y Tareas asíncronas
Comandos
Formulario para contacto
Emails
Async tasks
Procesar tareas asíncronas
Crear un comando para agregar usuarios
Seguridad
Security
Security Examples
Conclusiones
Crea una API Rest
Cierre
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Aportes 19
Preguntas 2
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 “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 ^^
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 ‘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.
Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.