How to access the Altorouter instance in my views - php

I'm new to php, I would like to have access to the $router instance in my views so that I can use the route names with $router->generate() in the view but I don't know how to do it?
I use Altorouter like this:
Index.php
$router = new AltoRouter();
$router->map( 'GET', '/post/[:id]/', 'PostController#find' );
$match = $router->match();
if ($match === false) {
throw new \Exception($error->404());
} else {
list($controller, $action) = explode('#', $match['target']);
if (is_callable(array($controller, $action))) {
$obj = new $controller();
call_user_func_array(array($obj, $action), array($match['params']));
} else {
throw new \Exception($error->500());
}
}
PostController.php
public function find($args)
{
$post = $this->PostModal->find($args[id]);
// View
View::render('post/show', compact('post'));
}
My class View.php which manages the views
public static function render(string $path, array $variables = [])
{
extract($variables);
ob_start();
require 'views/' . $path . '.html.php';
$pageContent = ob_get_clean();
require 'views/layouts/layout.html.php';
}

If you have the same problem as me, I resolved by adding
global $router;
in the render

Related

I can't create object php

I am just starting with php and I can't create this object.
I call my object with the variable $theClass is a concatenation of a namespace and a variable from a an array.
One var_dump of $theclass show me the right path... the problem start wen I try to create a new $theClass on variable($control) the var_dump show me nothing...
<?php
namespace App\Router;
class Router {
private $routes = [];
private $url;
public function __construct($url){
$this->url = $url;
}
public function get($path, $action){
$this->routes['GET'][$path] = $action;
}
public function match(){
foreach ($this->routes as $key => $routes) {
foreach ($routes as $path => $action) {
if ($this->url === $path) {
$elements = explode('#', $action);
//$this->callController($elements);
$theClass = "App\Controller\\$elements[0]";
// I try this way to 'App\Controller\\' . $elements[0];
var_dump($theClass);
$method = $elements[1];
var_dump($method);
$control = new $theClass();
$control->$method();
}
}
header('HTTP/1.0 404 Not Found');
}
}
}

PHP get dynamically the namespace off a class by concating it

I have a string, route, and i explode it and then i have a classname. $callback = explode('#', $callback); $callback[0] is the classname. I am making a router and based on the class and methed i return this.
I want to get the full namespace and when i use this then it works but now i want to make it dynamically.
How do i concat BaseController to the ::class?
BasController::class
$fullclass = HERE I NEED THE FULL NAMESPACE$callback[0];
$class = new $fullclass;
$method = $callback[1];
$class->$method();
Exaple index.php
Router::route('/user/{id}/' , 'BaseController#show');
Router::execute($_SERVER['REQUEST_URI']);
Router:
namespace App;
class Router
{
private static $routes = array();
private function __construct()
{
}
private function __clone()
{
}
public static function route($pattern, $callback)
{
$pattern = $pattern;
self::$routes[$pattern] = $callback;
}
public static function execute($url)
{
foreach (self::$routes as $pattern => $callback) {
if ($pattern == $url) {
$callback = explode('#', $callback);
$fullclass = __NAMESPACE__ . '\\Controllers\\' . $callback[0];
$class = new $fullclass;
$method = $callback[1];
$class->$method();
}else{
echo 404;
}
}
}
}
BasController::class returns a full class name in string in that case you can simply concat any string on it. If $callback[0] is a string you can do below code.
$fullclass = BasController::class . $callback[0];
$class = new $fullclass;
$method = $callback[1];
$class->$method();
I hope you are trying to retrieve namespace
echo (new \ReflectionClass($object))->getNamespaceName() ;
If you are in that scope try
__NAMESAPCE__
See this document if you are looking for autoload
What i was looking for is giving the class as param into the route
Router::route('/user/{id}/' , App\Controllers\BaseController::class , 'show');

How i can create child view for parent view in PHP MVC?

When i type this address:
http://localhost/gamelvl/world-of-tanks/tankguide/
I can enter the tankguide view. Now inside this folder is another folder called ussr but when I create a controller and model for ussr I can not enter it with this address:
http://localhost/gamelvl/world-of-tanks/tankguide/ussr/
Now, any one can give me instructions on whether this is the right thing or other solutions for this?
routing app
<?php
class App
{
public $controller = 'index';
public $method = 'index';
public $params = [];
function __construct()
{
if (isset($_GET['url'])) {
$url = $_GET['url'];
$url = $this->parseUrl($url);
$this->controller = $url[0];
unset($url[0]);
if (isset($url[1])) {
$this->method = $url[1];
unset($url[1]);
}
$this->params = array_values($url);
}
$controllerurl = 'controllers/' . $this->controller . '.php';
if (file_exists($controllerurl)) {
require($controllerurl);
$object = new $this->controller;
$object->model($this->controller);
if (method_exists($object, $this->method)) {
call_user_func_array([$object, $this->method], $this->params);
}
}
}
function parseUrl($url)
{
filter_var($url, FILTER_SANITIZE_URL);
$url = rtrim($url, '/');
$url = explode('/', $url);
return $url;
}
}
?>
tankguide controller
<?php
class Tankguide extends Controller
{
function index()
{
$this->view('tankguide/index');
}
}
?>
core controller
<?php
class Controller
{
function __construct()
{
}
function view($viewUrl,$data=[])
{
require('header.php');
require('views/' . $viewUrl . '.php');
require('footer.php');
}
function model($modelUrl)
{
require('models/model_' . $modelUrl . '.php');
$classname = 'model_' . $modelUrl;
$this->model = new $classname;
}
}
?>
project structure
if (method_exists($object, $this->method)) will return false for the given url, because it is looking for a method called ussr on the Tankguide class. Either create a ussr method on that class

PHP MVC - return call_user_func_array() in a __construct

I am working on a MVC site, but I have a problem. I can not return anything from my controllers. I can do things like $this->someMethod() but not return "hello" I think it has to do with call_user_func_array() So how do I fix this?
My code:
Router:
Class App
{
protected $controller = 'home';
protected $method = 'index';
protected $parameters = [];
public function __construct()
{
$url = $this->Url();
if(file_exists('../app/controllers/'. $url[0] .'.php')){
$this->controller = $url[0];
unset($url[0]);
}
require_once '../app/controllers/'. $this->controller .'.php';
$this->controller = new $this->controller;
if (isset($url[1])){
if (method_exists($this->controller, $url[1])){
$this->method = $url[1];
unset($url[1]);
}
}
$this->parameters = $url ? array_values($url) : [''];
call_user_func_array([$this->controller, $this->method], $this->parameters);
}
public function Url()
{
if(isset($_GET['url'])){
$url = filter_var(rtrim($_GET['url'], '/'), FILTER_SANITIZE_URL);
$exploded_url = explode('/', $url);
return $exploded_url;
}
}
}
Public Index.php:
<?php
require_once '../app/core/init.php';
$app = new App;
A controller:
class Home extends Controller
{
public function index($name)
{
//this works.
$this->view('index');
//this does not work.
return "hello";
}
}
So how do I solve it, so the return works too?

Dynamic instantation of namespaced methods in php

There are few routers out there but I decided to create a very simple route for a very light site.
Here is my index.php
$route = new Route();
$route->add('/', 'Home');
$route->add('/about', 'About');
$route->add('/contact', 'Contact');
Here is my router:
<?php namespace Laws\Route;
use Laws\Controller\Home;
class Route
{
private $_uri = array();
private $_method = array();
private $_route;
public function __construct()
{
}
public function add($uri, $method = null)
{
$this->_uri[] = '/' . trim($uri, '/');
if ($method != null) {
$this->_method[] = $method;
}
}
public function submit()
{
$uriGetParam = isset($_GET['uri']) ? '/' . $_GET['uri'] : '/';
foreach ($this->_uri as $key => $value) {
if (preg_match("#^$value$#", $uriGetParam)) {
$useMethod = $this->_method[$key];
new $useMethod(); // this returns an error (cannot find Home'
new Home(); // this actually works.
}
}
}
}
new $useMethod(); does not work. returns error 'cannot find Home'
new Home(); actually works.
What am I missing here?
You can use your concurrent way for calling a class or you can use this:
call_user_func(array($classname,$methodname))

Categories