PHP MVC "route not found" - php

i am using php mvc and when i try to edit a specific row, it says, "no route matched" but the route is well defined.
Here is the route for match
$router->add('{controller}/{id:\d+}/{action}');
and here is Router.php.
<?php
namespace Core;
/**
*Router
*/
class Router
{
protected $routes = [];
//saves the parameter from the matched route
protected $params = [];
/**
*Below, params=[] indicates that the paramentes in the url can be empty
*/
public function add($route, $params = [])
{
// Convert the route to a regular expression: escape forward slashes
$route = preg_replace('/\//', '\\/', $route);
// Convert variables e.g. {controller}
$route = preg_replace('/\{([a-z]+)\}/', '(?P<\1>[a-z-]+)', $route);
// Convert variables with custom regular expressions e.g. {id:\d+}
$route = preg_replace('/\{([a-z]+):([^\}]+)\}/', '(?P<\1>\2)', $route);
// Add start and end delimiters, and case insensitive flag
$route = '/^' . $route . '$/i';
$this->routes[$route] = $params;
}
/**
*matches the route and sets the parameters
* $url: The route URL
* returns true is match is found else flase
*/
public function match($url)
{
//Matches to the fixed URL format /controller/action
//$reg_exp = "/^(?P<controller>[a-z-]+)\/(?P<action>[a-z-]+)$/";
foreach ($this->routes as $route => $params) {
if (preg_match($route, $url, $matches))
{
//get named capture group values
//$params = [];
foreach ($matches as $key => $match) {
if (is_string($key))
{
$params[$key] = $match;
}
}
$this->params = $params;
return true;
}
}
return false;
}
// foreach ($this->routes as $route => $params) {
// if ($url == $route) {
// $this->params = $params;
// return true;
// }
// }
// return false;
// if (preg_match($reg_exp, $url, $matches))
// {
//
//
// }
//gets the currently matched parameters
public function getParams()
{
return $this->params;
}
public function dispatch($url)
{
$url = $this->removeQueryStringVariables($url);
if($this->match($url)){
$controller = $this->params['controller'];
$controller = $this->convertToStudlyCaps($controller); //Text can easily be converted from uppercase or lowercase to sTudLYcAPs
//$controller = "App\Controllers\\$controller";
$controller = $this->getNameSpace() . $controller;
if (class_exists($controller)){
$controller_object = new $controller($this->params);
$action = $this->params['action'];
$action = $this->convertToCamelCase($action);
if (is_callable([$controller_object, $action]))
{
$controller_object->$action();
}else{
throw new \Exception("Method $action (in controller $controller) not found");
}
}else{
throw new \Exception("Controller class $controller not found");
}
}else {
throw new \Exception("No route matched");
}
}
/**
*Convert the string with hypens to StudlyCaps,
*e.g. post-authors => PostAuthors
*/
protected function convertToStudlyCaps($string)
{
return str_replace(' ', '', ucwords(str_replace('-', ' ', $string)));
}
/**
*Convert the string with hypens to camelCase,
*e.g. add-new => addNew
*/
protected function convertToCamelCase($string)
{
return lcfirst($this->convertToStudlyCaps($string));
}
/**
*This removes query string variable i.e. posts/index&page=1 => posts/index
*
*/
protected function removeQueryStringVariables($url)
{
if($url != '')
{
$parts = explode('&', $url, 2);
if(strpos($parts[0], '=') === false){
$url = $parts[0];
}
else{
$url = '';
}
}
return $url;
}
/*
*Get the namespace for the controller class. The namespace defined in the
*route parameters is added if present.
*/
protected function getNameSpace()
{
$namespace = 'App\Controllers\\';
if(array_key_exists('namespace', $this->params))
{
$namespace .= $this->params['namespace'] . '\\';
}
return $namespace;
}
}
?>
P.S. i can add values to database but cannot edit it, as it says route not matched. if it helps,here is index.php:
<?php
/**
* FIRST CONTROLLER
*
*/
/**
*Twig
*/
require_once dirname(__DIR__) . '/vendor/Twig/lib/Twig/autoload.php';
Twig_Autoloader::register();
/**
*AutoLoader
*
*/
spl_autoload_register(function ($class){
$root = dirname(__DIR__); //gets the parent directory
$file = $root . '/' . str_replace('\\', '/', $class) . '.php';
if (is_readable($file))
{
require $root . '/' . str_replace('\\', '/', $class) . '.php';
}
});
/**
*Error and Exception handling
*
*/
error_reporting(E_ALL);
set_error_handler('Core\Error::errorHandler');
set_exception_handler('Core\Error::exceptionHandler');
/**
*Routing
*
*/
//require '../Core/Router.php';
$router = new Core\Router();
//Routes
$router->add('', ['controller' => 'Home', 'action' => 'index']);
$router->add('{controller}/{action}');
$router->add('admin/{controller}/{action}', ['namespace' => 'Admin']);
$router->add('{controller}/{id:\d+}/{action}');
$router ->dispatch($_SERVER['QUERY_STRING']);
/*
// Display the routing table
echo '<pre>';
//var_dump($router->getRoutes());
echo htmlspecialchars(print_r($router->getRoutes(),true));
echo '<pre>';
//Match the requested route
$url = $_SERVER['QUERY_STRING'];
if ($router->match($url)) {
echo '<pre>';
var_dump($router->getParams());
echo '<pre>';
}else{
echo "No Route Found For URL '$url'";
}
*/
?>

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');
}
}
}

Parameters in Custom Router PHP

I am trying to create a custom router.
This is what I have so far:
<?php
/**
* Created by PhpStorm.
* User: antony
* Date: 5/30/16
* Time: 3:31 PM
*/
namespace Fab\Router;
class Router
{
private $_getUri = array();
private $_getController = array();
private $_getMethod = array();
private $_postUri = array();
private $_postController = array();
private $_postMethod = array();
public function __construct()
{
}
/**
* Build a collection of internal GET URLs to look for
* #param $uri - The url that the user types in the browser
* #param $controller - The controller that will handle the url
* #param $method - The method of the controller that will run
*/
public function get($uri, $controller, $method)
{
$this->_getUri[] = $uri;
$this->_getController[] = $controller;
$this->_getMethod[] = $method;
}
/**
* Build a collection of internal POST URLs to look for
* #param $uri - The url that the user types in the browser
* #param $controller - The controller that will handle the url
* #param $method - The method of the controller that will run
*/
public function post($uri, $controller, $method)
{
$this->_postUri[] = $uri;
$this->_postController[] = $controller;
$this->_postMethod[] = $method;
}
public function submit()
{
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
var_dump($_SERVER['REQUEST_URI']);
echo "\n";
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); //get the url
var_dump($path);
foreach ($this->_getUri as $key => $value)
{
if (preg_match("#^$value$#", $path))
{
// echo $key . ' => ' . $value; //See what the $path returns
//Instantiate Controller
$controller = 'Fab\Controllers\\' . $this->_getController[$key];
$controller = new $controller();
//Call the appropriate method
$method = $this->_getMethod[$key];
$controller->$method();
}
}
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); //get the url
foreach ($this->_postUri as $key => $value)
{
if (preg_match("#^$value$#", $path))
{
//echo $key . ' => ' . $value; //See what the $path returns
//Instantiate Controller
$controller = 'Fab\Controllers\\' . $this->_postController[$key];
$controller = new $controller();
//Call the appropriate method
$method = $this->_postMethod[$key];
$controller->$method();
}
}
}
}
}
This allows me to say in my index.php something like:
$router->get('/portfolio', 'MainController', 'portfolio');
What I want to do now is to create an individual page for every item in the portfolio and give it a unique URL.
For example, if I have the item 'dinosaur' in my portfolio, I want to be able to say:
$router->get('/portfolio/dinosaur', 'MainController', 'searchIfDinosaurExistsInDatabase');
So generally, I would like to have in my index sth like:
$router->get('/portfolio/{item}', 'MainController', 'searchInDbForItem');
How can I modify my router in order to achieve this?
You need to add an regular expression to route. For example like this (it's a very simple example):
$router->get('/portfolio/[\w\d]+', 'MainController', 'searchInDbForItem');`
And you need use preg_match for comparison a route and an url.
It's a very simple example of router https://github.com/newage/example/blob/master/core/Route/HttpRoute.php

Failed to load function

i tried to generate URL with load another class
the error messages is :
Notice: Undefined variable: user in
/var/www/html/lab/system/core/Router.php on line 260
Warning: call_user_func_array() expects parameter 1 to be a valid
callback, first array member is not a valid class name or object in
/var/www/html/lab/system/core/Router.php on line 260
Router.php :
<?php
require_once 'class.php';
class AltoRouter {
/**
* #var array Array of all routes (incl. named routes).
*/
protected $routes = array();
/**
* #var array Array of all named routes.
*/
protected $namedRoutes = array();
/**
* #var string Can be used to ignore leading part of the Request URL (if main file lives in subdirectory of host)
*/
protected $basePath = '';
/**
* #var array Array of default match types (regex helpers)
*/
protected $matchTypes = array(
'i' => '[0-9]++',
'a' => '[0-9A-Za-z]++',
'h' => '[0-9A-Fa-f]++',
'*' => '.+?',
'**' => '.++',
'' => '[^/\.]++'
);
/**
* Create router in one call from config.
*
* #param array $routes
* #param string $basePath
* #param array $matchTypes
*/
public function __construct( $routes = array(), $basePath = '', $matchTypes = array() ) {
$this->addRoutes($routes);
$this->setBasePath($basePath);
$this->addMatchTypes($matchTypes);
}
/**
* Retrieves all routes.
* Useful if you want to process or display routes.
* #return array All routes.
*/
public function getRoutes() {
return $this->routes;
}
/**
* Add multiple routes at once from array in the following format:
*
* $routes = array(
* array($method, $route, $target, $name)
* );
*
* #param array $routes
* #return void
* #author Koen Punt
* #throws Exception
*/
public function addRoutes($routes){
if(!is_array($routes) && !$routes instanceof Traversable) {
throw new \Exception('Routes should be an array or an instance of Traversable');
}
foreach($routes as $route) {
call_user_func_array(array($this, 'map'), $route);
}
}
/**
* Set the base path.
* Useful if you are running your application from a subdirectory.
*/
public function setBasePath($basePath) {
$this->basePath = $basePath;
}
/**
* Add named match types. It uses array_merge so keys can be overwritten.
*
* #param array $matchTypes The key is the name and the value is the regex.
*/
public function addMatchTypes($matchTypes) {
$this->matchTypes = array_merge($this->matchTypes, $matchTypes);
}
/**
* Map a route to a target
*
* #param string $method One of 5 HTTP Methods, or a pipe-separated list of multiple HTTP Methods (GET|POST|PATCH|PUT|DELETE)
* #param string $route The route regex, custom regex must start with an #. You can use multiple pre-set regex filters, like [i:id]
* #param mixed $target The target where this route should point to. Can be anything.
* #param string $name Optional name of this route. Supply if you want to reverse route this url in your application.
* #throws Exception
*/
public function map($method, $route, $target, $name = null) {
$this->routes[] = array($method, $route, $target, $name);
if($name) {
if(isset($this->namedRoutes[$name])) {
throw new \Exception("Can not redeclare route '{$name}'");
} else {
$this->namedRoutes[$name] = $route;
}
}
return;
}
/**
* Reversed routing
*
* Generate the URL for a named route. Replace regexes with supplied parameters
*
* #param string $routeName The name of the route.
* #param array #params Associative array of parameters to replace placeholders with.
* #return string The URL of the route with named parameters in place.
* #throws Exception
*/
public function generate($routeName, array $params = array()) {
// Check if named route exists
if(!isset($this->namedRoutes[$routeName])) {
throw new \Exception("Route '{$routeName}' does not exist.");
}
// Replace named parameters
$route = $this->namedRoutes[$routeName];
// prepend base path to route url again
$url = $this->basePath . $route;
if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) {
foreach($matches as $match) {
list($block, $pre, $type, $param, $optional) = $match;
if ($pre) {
$block = substr($block, 1);
}
if(isset($params[$param])) {
$url = str_replace($block, $params[$param], $url);
} elseif ($optional) {
$url = str_replace($pre . $block, '', $url);
}
}
}
return $url;
}
/**
* Match a given Request Url against stored routes
* #param string $requestUrl
* #param string $requestMethod
* #return array|boolean Array with route information on success, false on failure (no match).
*/
public function match($requestUrl = null, $requestMethod = null) {
$params = array();
$match = false;
// set Request Url if it isn't passed as parameter
if($requestUrl === null) {
$requestUrl = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
}
// strip base path from request url
$requestUrl = substr($requestUrl, strlen($this->basePath));
// Strip query string (?a=b) from Request Url
if (($strpos = strpos($requestUrl, '?')) !== false) {
$requestUrl = substr($requestUrl, 0, $strpos);
}
// set Request Method if it isn't passed as a parameter
if($requestMethod === null) {
$requestMethod = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
}
foreach($this->routes as $handler) {
list($method, $_route, $target, $name) = $handler;
$methods = explode('|', $method);
$method_match = false;
// Check if request method matches. If not, abandon early. (CHEAP)
foreach($methods as $method) {
if (strcasecmp($requestMethod, $method) === 0) {
$method_match = true;
break;
}
}
// Method did not match, continue to next route.
if(!$method_match) continue;
// Check for a wildcard (matches all)
if ($_route === '*') {
$match = true;
} elseif (isset($_route[0]) && $_route[0] === '#') {
$pattern = '`' . substr($_route, 1) . '`u';
$match = preg_match($pattern, $requestUrl, $params);
} else {
$route = null;
$regex = false;
$j = 0;
$n = isset($_route[0]) ? $_route[0] : null;
$i = 0;
// Find the longest non-regex substring and match it against the URI
while (true) {
if (!isset($_route[$i])) {
break;
} elseif (false === $regex) {
$c = $n;
$regex = $c === '[' || $c === '(' || $c === '.';
if (false === $regex && false !== isset($_route[$i+1])) {
$n = $_route[$i + 1];
$regex = $n === '?' || $n === '+' || $n === '*' || $n === '{';
}
if (false === $regex && $c !== '/' && (!isset($requestUrl[$j]) || $c !== $requestUrl[$j])) {
continue 2;
}
$j++;
}
$route .= $_route[$i++];
}
$regex = $this->compileRoute($route);
$match = preg_match($regex, $requestUrl, $params);
}
if(($match == true || $match > 0)) {
if($params) {
foreach($params as $key => $value) {
if(is_numeric($key)) unset($params[$key]);
}
}
return array(
'target' => $target,
'params' => $params,
'name' => $name
);
}
}
return false;
}
/**
* Compile the regex for a given route (EXPENSIVE)
*/
private function compileRoute($route) {
if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) {
$matchTypes = $this->matchTypes;
foreach($matches as $match) {
list($block, $pre, $type, $param, $optional) = $match;
if (isset($matchTypes[$type])) {
$type = $matchTypes[$type];
}
if ($pre === '.') {
$pre = '\.';
}
//Older versions of PCRE require the 'P' in (?P<named>)
$pattern = '(?:'
. ($pre !== '' ? $pre : null)
. '('
. ($param !== '' ? "?P<$param>" : null)
. $type
. '))'
. ($optional !== '' ? '?' : null);
$route = str_replace($block, $pattern, $route);
}
}
return "`^$route$`u";
}
}
$router = new AltoRouter();
$user = new Users();
$router->setBasePath('/lab/system/core/Router.php');
############################################################
$router->map('GET', '/home', function()
{
echo 'Home page';
}, 'home');
$router->map('GET', '/user', function()
{
call_user_func_array(array($user, 'user'), array());
}, 'user');
############################################################
$match = $router->match();
if($match && is_callable($match['target']))
{
call_user_func_array($match['target'], $match['params']);
}
else
{
echo "404 Not Found";
}
?>
class.php
<?php
class Users
{
function user()
{
echo "User page";
}
}
?>
anyone can explain it? thanks
did you try this ?
$router->map('GET', '/user', function($user)
{
call_user_func_array(array($user, 'user'), array());
}, 'user');

How can I make a router in PHP?

I'm currently developing a router for one of my projects and I need to do the following:
For example, imagine we have this array of set routes:
$routes = [
'blog/posts' => 'Path/To/Module/Blog#posts',
'blog/view/{params} => 'Path/To/Module/Blog#view',
'api/blog/create/{params}' => 'Path/To/Module/API/Blog#create'
];
and then if we pass this URL through: http://localhost/blog/posts it will dispatch the blog/posts route - that's fine.
Now, when it comes to the routes that require parameters, all I need is a method of implementing the ability to pass the parameters through, (i.e. http://localhost/blog/posts/param1/param2/param3 and the ability to prepend api to create http://localhost/api/blog/create/ to target API calls but I'm stumped.
Here's something basic, currently routes can have a pattern, and if the application paths start with that pattern then it's a match. The rest of the path is turned into params.
<?php
class Route
{
public $name;
public $pattern;
public $class;
public $method;
public $params;
}
class Router
{
public $routes;
public function __construct(array $routes)
{
$this->routes = $routes;
}
public function resolve($app_path)
{
$matched = false;
foreach($this->routes as $route) {
if(strpos($app_path, $route->pattern) === 0) {
$matched = true;
break;
}
}
if(! $matched) throw new Exception('Could not match route.');
$param_str = str_replace($route->pattern, '', $app_path);
$params = explode('/', trim($param_str, '/'));
$params = array_filter($params);
$match = clone($route);
$match->params = $params;
return $match;
}
}
class Controller
{
public function action()
{
var_dump(func_get_args());
}
}
$route = new Route;
$route->name = 'blog-posts';
$route->pattern = '/blog/posts/';
$route->class = 'Controller';
$route->method = 'action';
$router = new Router(array($route));
$match = $router->resolve('/blog/posts/foo/bar');
// Dispatch
if($match) {
call_user_func_array(array(new $match->class, $match->method), $match->params);
}
Output:
array (size=2)
0 => string 'foo' (length=3)
1 => string 'bar' (length=3)
This is a basic version - simply just a concept version to show functionality and I wouldn't suggest using it in a production environment.
$routes = [
'blog/view' => 'Example#index',
'api/forum/create' => 'other.php'
];
$url = explode('/', $_GET['url']);
if (isset($url[0]))
{
if ($url[0] == 'api')
{
$params = array_slice($url, 3);
$url = array_slice($url, 0, 3);
}
else
{
$params = array_slice($url, 2);
$url = array_slice($url, 0, 2);
}
}
$url = implode('/', $url);
if (array_key_exists($url, $routes))
{
$path = explode('/', $routes[$url]);
unset($path[count($path)]);
$segments = end($path);
$segments = explode('#', $segments);
$controller = $segments[0];
$method = $segments[1];
require_once APP_ROOT . '/app/' . $controller . '.php';
$controller = new $controller;
call_user_func_array([$controller, $method], $params);
}

Call to a member function on a non-object from another class [duplicate]

This question already has answers here:
Call to a member function on a non-object [duplicate]
(8 answers)
Closed 9 years ago.
I am learning oop and trying to implement php standards PSR-0 & PSR-1 along the way. I have started by creating a small MVC framework based on Swiftlet.
I am trying to call functions from my base View controller within the Controller that I am calling from the url and I get 'Call to a member function set() on a non-object in'.
All the classes load ok. So in my controller I call $this->view->set('helloWorld', 'Hello world!'); but I get an error. I had some trouble trying to get the namespace structure right so maybe this is the cause?
Here is the file structure:
index.php
lib/bootstrap.php
lib/view.php
lib/controller.php
app/controllers/index.php
and here is the code for each:
index.php
<?php
namespace MVC;
// Bootstrap the application
require 'lib/Bootstrap.php';
$app = new lib\Bootstrap;
spl_autoload_register(array($app, 'autoload'));
$app->run();
$app->serve();
bootstrap.php
namespace MVC\lib;
class Bootstrap
{
protected
$action = 'index',
$controller,
$hooks = array(),
$view
;
/**
* Run the application
*/
function run()
{
... Code that gets controller and the action form the url
$this->view = new \lib\View($this, strtolower($controllerName));
// Instantiate the controller
$controllerName = 'app\Controllers\\' . basename($controllerName);
$this->controller = new $controllerName();
// Call the controller action
$this->registerHook('actionBefore');
if ( method_exists($this->controller, $this->action) ) {
$method = new \ReflectionMethod($this->controller, $this->action);
if ( $method->isPublic() && !$method->isFinal() && !$method->isConstructor() ) {
$this->controller->{$this->action}();
} else {
$this->controller->notImplemented();
}
} else {
$this->controller->notImplemented();
}
return array($this->view, $this->controller);
}
<?php
namespace MVC\lib;
class Bootstrap
{
protected
$action = 'index',
$args = array(),
$config = array(),
$controller,
$hooks = array(),
$plugins = array(),
$rootPath = '/',
$singletons = array(),
$view
;
/**
* Run the application
*/
function run()
{
// Determine the client-side path to root
if ( !empty($_SERVER['REQUEST_URI']) ) {
$this->rootPath = preg_replace('/(index\.php)?(\?.*)?$/', '', $_SERVER['REQUEST_URI']);
if ( !empty($_GET['route']) ) {
$this->rootPath = preg_replace('/' . preg_quote($_GET['route'], '/') . '$/', '', $this->rootPath);
}
}
// Extract controller name, view name, action name and arguments from URL
$controllerName = 'Index';
if ( !empty($_GET['route']) ) {
$this->args = explode('/', $_GET['route']);
if ( $this->args ) {
$controllerName = str_replace(' ', '/', ucwords(str_replace('_', ' ', str_replace('-', '', array_shift($this->args)))));
}
if ( $action = $this->args ? array_shift($this->args) : '' ) {
$this->action = str_replace('-', '', $action);
}
}
if ( !is_file('app/Controllers/'. $controllerName . '.php') ) {
$controllerName = 'Error404';
}
$this->view = new \lib\View($this, strtolower($controllerName));
// Instantiate the controller
$controllerName = 'app\Controllers\\' . basename($controllerName);
$this->controller = new $controllerName();
// Call the controller action
$this->registerHook('actionBefore');
if ( method_exists($this->controller, $this->action) ) {
$method = new \ReflectionMethod($this->controller, $this->action);
if ( $method->isPublic() && !$method->isFinal() && !$method->isConstructor() ) {
$this->controller->{$this->action}();
} else {
$this->controller->notImplemented();
}
} else {
$this->controller->notImplemented();
}
$this->registerHook('actionAfter');
return array($this->view, $this->controller);
}
<?php
namespace MVC\lib;
class Bootstrap
{
protected
$action = 'index',
$args = array(),
$config = array(),
$controller,
$hooks = array(),
$plugins = array(),
$rootPath = '/',
$singletons = array(),
$view
;
/**
* Run the application
*/
function run()
{
// Determine the client-side path to root
if ( !empty($_SERVER['REQUEST_URI']) ) {
$this->rootPath = preg_replace('/(index\.php)?(\?.*)?$/', '', $_SERVER['REQUEST_URI']);
if ( !empty($_GET['route']) ) {
$this->rootPath = preg_replace('/' . preg_quote($_GET['route'], '/') . '$/', '', $this->rootPath);
}
}
// Extract controller name, view name, action name and arguments from URL
$controllerName = 'Index';
if ( !empty($_GET['route']) ) {
$this->args = explode('/', $_GET['route']);
if ( $this->args ) {
$controllerName = str_replace(' ', '/', ucwords(str_replace('_', ' ', str_replace('-', '', array_shift($this->args)))));
}
if ( $action = $this->args ? array_shift($this->args) : '' ) {
$this->action = str_replace('-', '', $action);
}
}
if ( !is_file('app/Controllers/'. $controllerName . '.php') ) {
$controllerName = 'Error404';
}
$this->view = new \lib\View($this, strtolower($controllerName));
// Instantiate the controller
$controllerName = 'app\Controllers\\' . basename($controllerName);
$this->controller = new $controllerName();
// Call the controller action
$this->registerHook('actionBefore');
if ( method_exists($this->controller, $this->action) ) {
$method = new \ReflectionMethod($this->controller, $this->action);
if ( $method->isPublic() && !$method->isFinal() && !$method->isConstructor() ) {
$this->controller->{$this->action}();
} else {
$this->controller->notImplemented();
}
} else {
$this->controller->notImplemented();
}
$this->registerHook('actionAfter');
return array($this->view, $this->controller);
}
lib/view.php
namespace lib;
class View
{
protected
$app,
$variables = array()
;
public
$name
;
/**
* Constructor
* #param object $app
* #param string $name
*/
public function __construct($app, $name)
{
$this->app = $app;
$this->name = $name;
}
/**
* Set a view variable
* #param string $variable
* #param mixed $value
*/
public function set($variable, $value = null)
{
$this->variables[$variable] = $value;
}
and finally app/controllers/index.php
namespace app\Controllers;
class index extends \lib\Controller
{
public function test()
{
// This gets the error
$this->view->set('helloWorld', 'Hello world!');
}
}
If that is all of the code in your controller, then $this->view is not an object.
Try running the following code:
namespace app\Controllers;
class index extends \lib\Controller
{
public function test()
{
var_dump( $this->view );
exit;
$this->view->set('helloWorld', 'Hello world!');
}
}
You also should know, that in PHP, the __construct() methods are not inherited.
I must have suffered some brain injury.
Oh .. and I fail to see, why this question has mvc tag. While you are trying to write MVC-like thing, the issue itself has no relation to MVC as architectural pattern.

Categories