I need to get all registed routes to work with into a controller.
In slim 3 it was possible to get the router with
$router = $container->get('router');
$routes = $router->getRoutes();
With $app it is easy $routes = $app->getRouteCollector()->getRoutes();
Any ideas?
If you use PHP-DI you could add a container definition and inject the object via constructor injection.
Example:
<?php
// config/container.php
use Slim\App;
use Slim\Factory\AppFactory;
use Slim\Interfaces\RouteCollectorInterface;
// ...
return [
App::class => function (ContainerInterface $container) {
AppFactory::setContainer($container);
return AppFactory::create();
},
RouteCollectorInterface::class => function (ContainerInterface $container) {
return $container->get(App::class)->getRouteCollector();
},
// ...
];
The action class:
<?php
namespace App\Action\Home;
use Psr\Http\Message\ResponseInterface;
use Slim\Http\Response;
use Slim\Http\ServerRequest;
use Slim\Interfaces\RouteCollectorInterface;
final class HomeAction
{
/**
* #var RouteCollectorInterface
*/
private $routeCollector;
public function __construct(RouteCollectorInterface $routeCollector)
{
$this->routeCollector = $routeCollector;
}
public function __invoke(ServerRequest $request, Response $response): ResponseInterface
{
$routes = $this->routeCollector->getRoutes();
// ...
}
}
This will display basic information about all routes in your app in SlimPHP 4:
$app->get('/tests/get-routes/', function ($request, $response, $args) use ($app) {
$routes = $app->getRouteCollector()->getRoutes();
foreach ($routes as $route) {
echo $route->getIdentifier() . " → ";
echo ($route->getName() ?? "(unnamed)") . " → ";
echo $route->getPattern();
echo "<br><br>";
}
return $response;
});
From there, one can use something like this to get the URL for a given route:
$routeParser = \Slim\Routing\RouteContext::fromRequest($request)->getRouteParser();
$path = $routeParser->urlFor($nameofroute, $data, $queryParams);
With the following caveats:
this will only work for named routes;
this will only work if the required route parameters are provided -- and there's no method to check whether a route takes mandatory or optional route parameters.
there's no method to get the URL for an unnamed route.
Related
Suppose that in my dependencies.php file I setup this container:
<?php
$container = $app->getContainer();
$container['db'] = function($config)
{
$db = $config['settings']['db'];
$pdo = new PDO("mysql:host=" . $db['host'] . ";port=" . $db['port'] .
";dbname=" . $db['dbname'] . ";charset=" . $db['charset'], $db['user'], $db['pass']);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
return $pdo;
};
I can use this container inside my route, called for example table.php:
<?php
use Slim\Http\Request;
use Slim\Http\Response;
$app->get('/table/get_table', function (Request $request, Response $response, array $args)
{
$sql = $this->db->prepare("SELECT * FROM some_table");
$sql->execute();
$result = $sql->fetchAll();
return $response->withJson($result);
});
this is basically the default usage, right? Said that, how can I instead use the db container from other classes? Supposes I have created a class called TableUtility and imported inside the table.php:
class TableUtility
{
function GetTableFromDb()
{
$sql = $this->db->prepare("SELECT * FROM some_table");
$sql->execute();
$result = $sql->fetchAll();
return $response->withJson($result);
}
}
as you can see I moved the logic of PDO inside GetTableFromDb of TableUtility, how can I access to db container from this class?
The usage in table.php will be:
<?php
use Slim\Http\Request;
use Slim\Http\Response;
$app->get('/table/get_table', function (Request $request, Response $response, array $args)
{
$tableUtility = new TableUtility();
return $response->withJson($tableUtility->GetTableFromDb());
});
actually I get in TableUtility:
Call to a member function prepare() on null
The full name for what you refer to as container is Dependency Injection Container. It is supposed to contain dependencies for objects. Passing this container to objects is considered bad practice. Instead you should pass only required dependencies for that object, which in your case is to pass db to $tableUtility. This is usually used by passing dependencies when constructing the object, or using setter methods. In your case you can refactor your code like this:
class TableUtility
{
function __construct($db) {
$this->db = $db;
}
}
Now in any method of TableUtility class, you have access to db object using $this->db but you'll need to pass db to class constructor whenever you create a new object. So you also need to do this:
$app->get('/table/get_table', function (Request $request, Response $response, array $args)
{
$tableUtility = new TableUtility($this->db);
// rest of the code
});
i a, having a link which sends public to view timeline of a specific user by passing variable in route.
<a href="<?php echo $baseLocation ?>/bnb-details/<?php echo $row['username']?>" >View</a>
and my route is defined as:
$app->get('/bnb-details/{name}', function (Request $request, Response $response, $args) {
include_once('bnb-details.php');
return $response; });
how can i pass the {name} args in the bnb-details.php ??
any kind of help would be appriciated.
you can use like this :
you should pass parametere from args to variable
$app->get('/bnb-details/{name}', function (\Slim\Http\Request $request, \Slim\Http\Response $response, $args) {
$name = $args['name'];
include_once('bnb-details.php');
return $response;
});
then use
echo $name;
in bnb-details.php
There is one view, and one controller, it is necessary, with the use of the get parameter, to change the path by the link. So in the end it turned out like this:
Upcoming -> http://mywebsite.com/tournaments?type=upcoming
Finished -> http://mywebsite.com/tournaments?type=finished
Here is the controller which will process your GET variable
Controller
<?php
class Demo_controller extends CI_Controller
{
public function demo($id)
{
echo $id; //the id which you will get in URL string
}
}
?>
View File where you will pass the Variable
<?php
$id = "1";//dyanmic id which will be pased with the form
echo form_open('demo/demos-function'.$id);
//in between your code
echo form_close
?>
Routes
Inside routes.php
$route['demo/demos-function/(:any)] = Demo_controller/demo/$1
No need to change the $1 it will explain the routes that it is having URL paramater.
So Ultimately Your link will be
https://localhost/demo/demos-function/1
https://localhost/demo/demos-function/2
In Codeigniter Url like this :
Upcoming -> http://mywebsite.com/controller/method/upcoming
Finished -> http://mywebsite.com/controller/method/finished
public function method_name()
{
$type = $this->uri->segment(3); // third level value of URL - Segment(1) is controller and followed by method and query string
if($type == 'upcoming')
{
echo $type;
$this->load->view('upcoming');
}
else
{
echo $type;
$this->load->view('finished');
}
}
I have a route defined in my Slim app like so:
$app->get('/marcas/:id', 'getMarcas');
My callback function is defined as:
function getMarcas($id) {
$sql = "SELECT * FROM marcas WHERE id=:id";
try {
$db = getConnection();
$stmt = $db->prepare($sql);
$stmt->bindParam("id", $id);
$stmt->execute();
$marcas = $stmt->fetchObject();
$db = null;
echo json_encode($mrcas);
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
How can I apply a route condition like:
->conditions(array('id' => '[0-9]{2,}'));
Thanks
You can assign conditions exactly the way you guessed. See the Route Conditions documentation for details: http://docs.slimframework.com/#Route-Conditions
you can use
$app = new \Slim\Slim();
$app->get('/hello/:firstName/:lastName', $callable)
->conditions(array('lastName' => '[0-9]{2,}'));
with calling of get/post
i need advice on how i can implement this action helper. currently, i have something like
class Application_Controller_Action_Helper_AppendParamsToUrl extends Zend_Controller_Action_Helper_Abstract {
function appendParamsToUrl($params = array()) {
$router = Zend_Controller_Front::getInstance()->getRouter();
$url = $router->assemble($params);
if (!empty($_SERVER['QUERY_STRING'])) {
$url .= $_SERVER['QUERY_STRING'];
}
return $url;
}
}
but as you can see, i think the function should be a static function? but how will that find into this Zend_Controller_Action_Helper thingy?
Make the function public and in your BootStrap.php ensure the controller helper can be autoloaded
// add paths to controller helpers
Zend_Controller_Action_HelperBroker::addPath( APPLICATION_PATH .'/controllers/helpers');
You should then be able to call the helper from your controller via
$this->_helper->appendParamsToUrl->appendParamsToUrl();
You can also rename appendParamsToUrl() function to direct()
function direct( $params = array() ) {...}
In this case, you'll be able to access it from controller with
$this->_helper->appendParamsToUrl( $params );