I'm creating a new Slim project and getting the following error:
Slim Application Error:
The application could not run because of the following error:
Error Details
Type: Slim\Exception\HttpNotFoundException
Code: 404
Message: Not found.
File: C:\xampp\htdocs\MyApi\vendor\slim\slim\Slim\Middleware\RoutingMiddleware.php
Line: 91
Trace
#0 C:\xampp\htdocs\MyApi\vendor\slim\slim\Slim\Middleware\RoutingMiddleware.php(57): Slim\Middleware\RoutingMiddleware->performRouting(Object(Slim\Psr7\Request))
#1 C:\xampp\htdocs\MyApi\vendor\slim\slim\Slim\MiddlewareDispatcher.php(124): Slim\Middleware\RoutingMiddleware->process(Object(Slim\Psr7\Request), Object(Slim\Routing\RouteRunner))
#2 C:\xampp\htdocs\MyApi\vendor\slim\slim\Slim\Middleware\ErrorMiddleware.php(89): class#anonymous->handle(Object(Slim\Psr7\Request))
#3 C:\xampp\htdocs\MyApi\vendor\slim\slim\Slim\MiddlewareDispatcher.php(124): Slim\Middleware\ErrorMiddleware->process(Object(Slim\Psr7\Request), Object(class#anonymous))
#4 C:\xampp\htdocs\MyApi\vendor\slim\slim\Slim\MiddlewareDispatcher.php(65): class#anonymous->handle(Object(Slim\Psr7\Request))
#5 C:\xampp\htdocs\MyApi\vendor\slim\slim\Slim\App.php(174): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request))
#6 C:\xampp\htdocs\MyApi\vendor\slim\slim\Slim\App.php(158): Slim\App->handle(Object(Slim\Psr7\Request))
#7 C:\xampp\htdocs\MyApi\public\index.php(18): Slim\App->run()
#8 {main}
Here is my index.php
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require '../vendor/autoload.php';
$app = AppFactory::create();
$app->addRoutingMiddleware();
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
$app->get('/hello/{name}', function (Request $request, Response $response, array $args) {
$name = $args['name'];
$response->getBody()->write("Hello, $name");
return $response;
});
$app->run();
This might be a basic problem.But I am new.Need help please.
To solve the problem with Slim 4 here is what I did :
1/ Just after
$app = AppFactory::create();
I added :
$app->setBasePath("/myapp/api"); // /myapp/api is the api folder (http://domain/myapp/api)
2/ In my .htaccess :
RewriteEngine on
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteRule ^api/(.*)$ api/index.php/$1
3/ Finaly to handle the 'HttpNotFoundException' Slim Exception I added a try/catch (I don't know why Slim doesn't handle it internaly => maybe to give us more possibility?)
try {
$app->run();
} catch (Exception $e) {
// We display a error message
die( json_encode(array("status" => "failed", "message" => "This action is not allowed")));
}
Hope it can help
** Edited => To force Slim to handle Exceptions, after : **
$app = AppFactory::create();
add :
$app->addErrorMiddleware(true, true, true);
Ref : http://www.slimframework.com/docs/v4/middleware/body-parsing.html
This worked for me (based on Mandien's answer).
I've just added index.php in setBasePath(...), no .htaccess needed.
$app->setBasePath("/myapp/public/index.php");
// Define app routes
$app->get('/hello/{name}', function (Request $request, Response $response, $args) {
$name = $args['name'];
$response->getBody()->write("Hello, $name");
return $response;
});
http://localhost/myapp/public/index.php/hello/world
shows Hello, world
Linux, Apache, Slim 4
I was getting the same error, let me describe what I was exactly doing and then how did it work!
I was running local server using the command on terminal php -S localhost:8002
The command returned Document root is /Users/Codeus/Desktop/ and error occured when I navigated to localhost:8002
Then again I ran localhost from the directory where index.php or whatever your is that you wanna run and it worked fine for me. For example, for me, it was two levels up then command php -S localhost:8002 returned Document root is /Users/Codeus/Desktop/myslim/src/public and this is exactly where my index.php file was. Hope this works for you as well.
If you are using slim and a newbie then try this code and it will work
Simply change your code a little.
Right now, you all have this code:
$app->get('/hello/{name}', function (Request $request, Response $response, array $args) { ... }
Change it to full naming convention:
$app->get('/[my-appname]/public/hello/{name}', function (Request $request, Response $response, array $args) { .. }
Full code
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
//here i used the url change to your project name on [my-appname]
$app->get('/[my-appname]/public/hello/{name}', function (Request $request,
Response $response, array $args) {
$name = $args['name'];
$response->getBody()->write("Hello, $name");
return $response;
});
$app->run();
After nearly 3 hours of intense browsing, I have come up with the solution which would be to downgrade the version of Slim framework from the project's root directory.
I was using v4.3.0 which due to some strange reasons didn't want to behave the way it is meant to and the resolution for which was beyond my understanding.
The steps would be as follows:
Go to the project root directory and type cmd in the file path for
the command prompt window.
Type in composer require slim/slim:3.*
Once done, you would then need to replace the pre-existing code on
public/index.php from your code editor with the below:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
//use Slim\Factory\AppFactory;
require '../vendor/autoload.php';
$app = new \Slim\App;
$app->get('/hello/{name}', function (Request $request, Response $response, array $args) {
$name = $args['name'];
$response->getBody()->write("Hello, $name");
return $response;
});
$app->run();
The above snippet is basically the intro page code but from Slim v3.12.3
Related
I am trying to learn slim framework and I am following the tutorial. What I would like is a detailed explanation of what the be low snippet of code is doing within the slim environment.
$app->get('/client/{name}'
The reason that I am asking is because in keep getting route not found. But I have yet to figure out why. The base route works. But when I added the twig and tried to route to that. It fails.
Now comes the code:
This part is in my webroot/public/index.php
<?php
use DI\Container;
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
use Twig\Error\LoaderError;
require __DIR__ . '/../vendor/autoload.php';
$container = new Container;
$settings = require __DIR__ . '/../app/settings.php';
$settings($container);
AppFactory::setContainer($container);
$app = AppFactory::create();
$app->addRoutingMiddleware();
$app->addErrorMiddleware(true, true, true);
// Create Twig
$twigPath = __DIR__ . "/../templates";
$twig = '';
try {
$twig = Twig::create($twigPath, ['cache' => false]);
} catch (LoaderError $e) {
echo "Error " . $e->getMessage();
}
// Add Twig-View Middleware
$app->add(TwigMiddleware::create($app, $twig));
$routes = require __DIR__ . '/../app/routes.php';
$routes($app);
$app->run();
This part is in the routes.php:
<?php
use Slim\App;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Views\Twig;
return function (App $app) {
$app->get('/', function (Request $request, Response $response, array $args) {
$response->getBody()->write("Hello world! Really?");
return $response;
});
$app->get('/client/{name}', function (Request $request, Response $response, $args) {
$view = Twig::fromRequest($request);
return $view->render($response, 'client_profiles.html', [
'name' => $args['name']
]);
})->setName('profile');
};
The first route works fine the second does not. According to what I am reading. It should work. https://www.slimframework.com/docs/v4/features/templates.html
I feel that if I knew what get is looking to do. I may be able to fix it and build a proper route.
When I dig into the $app->get which connects with the RouterCollecorProxy.php. There is the $pattern variable and $callable. The callable is the anonymous function that comes after the common in the
$app->get('/client/{name}', function <- this is the callable, right?
I see the map class which takes me to the createRoute which returns the $methods, $pattern, callable and a few other things.
I think the pattern is where my problem is.
I'm using slim 4, and the URL im using is http://localhost/MyApi/public/hello/WeAreLearningPHP
Details
Type: Slim\Exception\HttpNotFoundException
Code: 404
Message: Not found.
File: /Applications/XAMPP/xamppfiles/htdocs/MyApi/vendor/slim/slim/Slim/Middleware/RoutingMiddleware.php
Line: 91
Trace
0 /Applications/XAMPP/xamppfiles/htdocs/MyApi/vendor/slim/slim/Slim/Middleware/RoutingMiddleware.php(57): Slim\Middleware\RoutingMiddleware->performRouting(Object(Slim\Psr7\Request))
1 /Applications/XAMPP/xamppfiles/htdocs/MyApi/vendor/slim/slim/Slim/MiddlewareDispatcher.php(132): Slim\Middleware\RoutingMiddleware->process(Object(Slim\Psr7\Request), Object(Slim\Routing\RouteRunner))
2 /Applications/XAMPP/xamppfiles/htdocs/MyApi/vendor/selective/basepath/src/BasePathMiddleware.php(52): class#anonymous->handle(Object(Slim\Psr7\Request))
3 /Applications/XAMPP/xamppfiles/htdocs/MyApi/vendor/slim/slim/Slim/MiddlewareDispatcher.php(132): Selective\BasePath\BasePathMiddleware->process(Object(Slim\Psr7\Request), Object(class#anonymous))
4 /Applications/XAMPP/xamppfiles/htdocs/MyApi/vendor/slim/slim/Slim/Middleware/ErrorMiddleware.php(89): class#anonymous->handle(Object(Slim\Psr7\Request))
5 /Applications/XAMPP/xamppfiles/htdocs/MyApi/vendor/slim/slim/Slim/MiddlewareDispatcher.php(132): Slim\Middleware\ErrorMiddleware->process(Object(Slim\Psr7\Request), Object(class#anonymous))
6 /Applications/XAMPP/xamppfiles/htdocs/MyApi/vendor/slim/slim/Slim/MiddlewareDispatcher.php(73): class#anonymous->handle(Object(Slim\Psr7\Request))
7 /Applications/XAMPP/xamppfiles/htdocs/MyApi/vendor/slim/slim/Slim/App.php(208): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request))
8 /Applications/XAMPP/xamppfiles/htdocs/MyApi/vendor/slim/slim/Slim/App.php(192): Slim\App->handle(Object(Slim\Psr7\Request))
9 /Applications/XAMPP/xamppfiles/htdocs/MyApi/public/index.php(28): Slim\App->run()
10 {main}
----------------index.php-------------------
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Selective\BasePath\BasePathMiddleware;
use Slim\Factory\AppFactory;
require_once __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
// Add Slim routing middleware
$app->addRoutingMiddleware();
// Set the base path to run the app in a subdirectory.
// This path is used in urlFor().
$app->add(new BasePathMiddleware($app));
$app->addErrorMiddleware(true, true, true);
// Define app routes
$app->get('/', function (Request $request, Response $response) {
$response->getBody()->write('Hello, World!');
return $response;
})->setName('root');
// Run app
$app->run();
I would like structure the API in order to separate both the routing organization from actions in separate files.
The current code does not return any errors, but the parameters are not collected correctly.
Is there a simple way to organize into functions without the need for classes, or __invoke?, the application does not require it.
public/index.php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require '../vendor/autoload.php';
$app = new \Slim\App;
foreach (glob("../src/middleware/*.php") as $middleware) {
require $middleware;
}
require '../src/routes/routes.php';
$app->run();
src/routes/routes.php
$app->group('/v1', function () use ($app) {
$app->post('/register', 'registerParticipant');
});
src/middleware/registerParticipant.php
require '../lib/qrlib/vendor/qrlib.php';
function registerParticipant($request, $response, $args) {
// demo for testing
$foo= $request->post('foo');
echo "foo= ".$foo;
// more app logic
}
Replacing $foo= $request->post('foo'); with $foo= $request->getParam('foo'); did the trick.
src/middleware/registerParticipant.php
require '../lib/qrlib/vendor/qrlib.php';
function registerParticipant($request, $response, $args) {
// demo for testing
$foo= $request->getParam('foo');
echo "foo= ".$foo;
// more app logic
}
I am completelly new to Slim. I have used php for the last 3-4 years but I have always done everything from scratch. I want to learn this frameworks for some rest services I have to do.
I have followed a tutorial on the slim webpage to get a simple rest service working but I want to add a log system to see what is happening when something goes wrong or wathever.
This is what I have right know:
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require '../Slim/Slim.php';
\Slim\Slim::requisterAutoloader();
$application = new \Slim\App();
$logger = $application->log;
$logger->setEnabled(true);
$logger->setLevel(\Slim\Log::DEBUG);
$application->get(
'/hello/user',
function ()
{
GLOBAL $logger;
$logger->info("starting the handling function");
echo "<data>response</data>";
$logger->info("ending handling function");
});
$application->run();
?>
I also tried with monolog but I didn't get it working.
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
require '../vendor/autoload.php';
$logger = new \Flynsarmy\SlimMonolog\Log\MonologWriter(array(
'handlers' => array(
new \Monolog\Handler\StreamHandler('./logs/'.date('Y-m-d').'.log'),
),
));
$app = new Slim\App(array(
'log.writer' => $logger,
));
$app->get('/hello/{name}', function (Request $request, Response $response){
$name = $request->getAttribute('name');
$response->getBody()->write("Hello, $name");
//$app->log->writer("hola");
$this->logger->info("Slim-Skeleton '/' route");
return $response;
});
$app->run();
What I would really want is to have a daily log with warnings, debug, info... in the same file. Changing the file every day.
The slim-skeleton application shows how to integrate monolog.
Register the logger with the DI container:
$container['logger'] = function ($c) {
$settings = $c->get('settings')['logger'];
$logger = new \Monolog\Logger('test-app');
$logger->pushHandler(new Monolog\Handler\StreamHandler('php://stdout', \Monolog\Logger::DEBUG));
return $logger;
};
Use it in your closure:
$app->get('/hello/{name}', function (Request $request, Response $response){
$name = $request->getAttribute('name');
$response->getBody()->write("Hello, $name");
$this->get('logger')->info("Slim-Skeleton '/' route");
return $response;
});
The logs will out output to stdout, so you'll see the in your apache error log or if you're using the built-in PHP server, in the terminal.
I have been at this for hours now and can not seem to figure out why it's not working. This my first time using SLIM and my first exposure to middleware. I am trying to follow the tutorial listed on the slim website but just can't get to work.
My bootstrap code:
<?php
require '../vendor/autoload.php';
$app = new Slim\Slim();
$app->get('/test', function() {
echo 'Hello, World';
});
$mw = function ($request, $response, $next) {
$response->getBody()->write('BEFORE');
$response = $next($request, $response);
$response->getBody()->write('AFTER');
return $response;
};
$app->add($mw);
$app->run();
When I run just my slim url without the middleware it runs fine. I get Hello, World as the output when I runt http://mysite/test. But when I add the middleware code as listed on the slim site I get the following error:
Catchable fatal error: Argument 1 passed to Slim\Slim::add() must be an instance of Slim\Middleware, instance of Closure given, called in /Applications/XAMPP/xamppfiles/htdocs/project/api/public/index.php on line 22 and defined in /Applications/XAMPP/xamppfiles/htdocs/academy/api/vendor/slim/slim/Slim/Slim.php on line 1267
Am I missing something? Does the middleware require some other setup? The slim documentation is not very helpful when it comes to this. Any help appreciated.
You seem to have installed Slim 2. You are also mixing Slim 2 and Slim 3 syntax. To install Slim 3 issue the following command.
$ composer install slim/slim
Then use code like following:
<?php
require "vendor/autoload.php";
$app = new \Slim\App;
$mw = function ($request, $response, $next) {
$response->getBody()->write("BEFORE");
$response = $next($request, $response);
$response->getBody()->write("AFTER");
return $response;
};
$app->add($mw);
$app->get("/test", function ($request, $response) {
echo "Hello, World";
});
$app->run();