I created a project with Slim 3 and Twig using their simplest examples.
Folder structure is as follows:
- public
- index.php
- style.css
App code in index.php is as follows:
<?php
require 'vendor/autoload.php';
$app = new \Slim\App();
$container = $app->getContainer();
// Twig
$container['view'] = function ($container) {
$view = new \Slim\Views\Twig('src/views', [
'cache' => false // TODO
]);
// Instantiate and add Slim specific extension
$basePath = rtrim(str_ireplace('index.php', '', $container['request']->getUri()->getBasePath()), '/');
$view->addExtension(new Slim\Views\TwigExtension($container['router'], $basePath));
return $view;
};
$app->get('/', function ($request, $response, $args) {
return $this->view->render($response, 'index/index.html.twig');
})->setName('index');
$app->run();
Now, the problem is that trying to load /style.css shows the main page instead (index/index.html.twig). Why can I not access the style.css file?
The server I use it the PHP built-in development server, using the command:
php -S localhost:8000 -t public public/index.php
How can I load the assets? What's the issue here?
The cause was the PHP built-in development server being 'dumb'.
I had to include this check as the very first thing in the index.php file.
// To help the built-in PHP dev server, check if the request was actually for
// something which should probably be served as a static file
if (PHP_SAPI == 'cli-server') {
$url = parse_url($_SERVER['REQUEST_URI']);
$file = __DIR__ . $url['path'];
if (is_file($file)) return false;
}
Source: https://github.com/slimphp/Slim-Skeleton/blob/master/public/index.php
Another option I checked an works is run server inside public folder. You will not need that script:
cd public
php -S localhost:8000
Related
I am just starting to work with Slim PHP. What could be the reason that get is not recognized on server?
This route works: it returns required text https://mywebsite/back/public
This route doesn't work (Not Found): https://mywebsite/back/public/countries
I have just installed slim framework and added new index.php file.
<?php
require '../vendor/autoload.php';
$app = new \Slim\App();
$app->get('/', function($request, $response, $arg) {
$response->write("This route works");
});
$app->get('/countries', function($request, $response, $arg) {
$response->write("This route doesnt");
});
$app->run();
?>
What version are you using? If you are using version 4, you need to set the basePath.
$app->setBasePath('/back/public');
Also enable mod_rewrite and configure your .htaccess file.
I recommend you check this project on github slimphp/Slim-Skeleton. This is a boilerplate code for Slim 4 applications.
I'm starting a new project using Slim framework. So far it's going decently, everything I'm looking for in a micro framework. I have been away from the PHP world for a while so I am now getting to know the built in PHP web server. The only issue is this: How do I serve my static content?
For reference, here is my project layout:
project:
public folder
index.php
static/css/style.css
templates/index.html . # I'm using twig (coming from python Flask)
My template:
<html>
<link href="{{ base_url() }}/css/agency.css" rel="stylesheet">
<!-- other cool layout stuff -->
and my index.php (very minimal)
require 'vendor/autoload.php';
$app = new \Slim\App();
$app->get('/', function ($request, $response, $args) {
$response = $this->view->render($response, 'base.html');
return $response->write("Hello ");
});
$app->run();
When I start the built in php server from the command line, I do this:
php -S localhost:8080 -t public public/index.php
While this works great, when I try to access my static content, it just returns the rendered base.html file
Please let me know the best way to start this so static content is rendered correctly. Your help is appreciated.
So based on the documentation as pointed out by kuh-chan and Nima, I expanded it for both Slim purposes, as well as returning a 404 response if the file did not exist.
if (PHP_SAPI == 'cli-server') {
$url = parse_url($_SERVER['REQUEST_URI']);
$file = __DIR__ . $url['path'];
// check the file types, only serve standard files
if (preg_match('/\.(?:png|js|jpg|jpeg|gif|css)$/', $file)) {
// does the file exist? If so, return it
if (is_file($file))
return false;
// file does not exist. return a 404
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
printf('"%s" does not exist', $_SERVER['REQUEST_URI']);
return false;
}
}
I haven't found many questions and answers relating to this so far, so thought I would ask the question as it will greatly help me out as a beginner learning PHP and the Slim framework. It's pretty straightforward (i think).
So, I want to route my home page to another page called about.php. I'm using the Slim/Slim framework which is installed in my vendor folder. And I have an index.php file with the following code:
<?php
require '/vendor/autoload.php';
$app = new \Slim\Slim();
$app->get('/', function() use($app){
$app->render('about.php');
});
$app->run();
?>
I also have an about.php file, which does exist.
This is what's currently in my composer.json file:
"require": {
"monolog/monolog": "^1.22",
"slim/slim": "^3.7",
"twig/twig": "^1.32",
"slim/views": "^0.1.3"
}
When I run MAMP (set-up to access the project I am working on) to see the page, it's blank. Can anyone help me understand what I'm doing wrong?
I've then run this (removing the leading '/' from the require statement, and adding a line to display errors), and it displayed a 500 error:
<?php
ini_set('display_errors', 1);
require 'vendor/autoload.php';
$app = new \Slim\Slim();
$view = $app->view();
$view->parserOptions = array(
'debug' => true
$app->get('/', function() use($app){
$app->render('about.php');
});
$app->run();
?>
I'm unclear if you want about.php to be separate from your Slim application or not.
i.e. when someone goes to http://example.com/ do you want the browser's URL to change to http://example.com/about.php where about.php is a completely independent PHP file in the same directory as your index.php?
If you do then you need to redirect:
$app->get('/', function ($request, $response) {
return $response->withRedirect('/about.php');
});
More usually, Slim is used to route to and display all pages in your application and in this situation, you wouldn't see the .php in the URL. This is because our app always runs index.php regardless of the actual URL in the the browser's address bar.
In this situation, you would probably still redirect, but without the .php:
$app->get('/', function ($request, $response) {
return $response->withRedirect('/about');
});
You would also need a handler for /about otherwise Slim won't know what to do:
$app->get('/about', function ($request, $response) {
return $response->write("This is my about page");
});
We don't actually tend to write the HTML directly in our handler though. We use a renderer. There's two in the Slim project: PhpView and TwigView. The Skeleton application shows how the PhpView version works. You may also find the tutorial in the documentation useful.
Finally, if you see a 500, then you have a PHP error somewhere. The easiest way to find this is to ensure that the php.ini setting error_reporting is set to E_ALL and that display_errors is set to On.
As you've already discovered, Slim 3's main class is called App. You can also enable detailed error displays within Slim using:
$app = new Slim\App(['settings' => ['displayErrorDetails' => true]]);
Again, usually we have a separate settings.php file containing this configuration information as shown in the skeleton application.
Why does Slim 404 when I try to add an extension to the route?
<?php
require_once 'vendor/autoload.php';
$app = new \Slim\Slim();
$app->get('/test', function () {
echo 'route 1';
});
$app->get('/test.html', function () {
echo 'route 2';
});
$app->run();
http://localhost:8080/test works
http://localhost:8080/test.html throws a 404
I assume you are running the example using internal PHP webserver. Built-in server will consider request as a static file request if there is a dot in the SCRIPT_NAME. It is considered a feature and not a bug. See PHP bug #61286 for more info.
Your code should work fine with Apache or other webservers, assuming rewrite rules are set up correctly.
I'd like to run a Silex Application like this in Command Line:
$app = new Silex\Application();
$app->get('/hello/{name}', function($name) use($app) {
return 'Hello '.$app->escape($name);
});
$app->run();
I think for that purpose, i'd have to pass Symfony's Request Object as first parameter to the run method, but i've got no idea, where to set the Url-Path to make it work. Any Ideas? Or is there a better way to do this?
Here's a simple way to do it:
list($_, $method, $path) = $argv;
$request = Request::create($path, $method);
$app->run($request);
And then on the command line:
$ php console.php GET /
If you want to use silex in a command line, you need to use the Console Component, here a tutorial for silex: http://beryllium.ca/?p=481
Then you are able to call a twig (symfony) service, and to forward an action !
http://symfony.com/doc/current/cookbook/console/console_command.html#getting-services-from-the-service-container