Failed to load function - php

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

Related

PHP: Get the timezone from where the application was accessed

Laravel 7.x
I need to access the timezone from where the application was accessed. I am only getting UTC in return from echo date_default_timezone_get();.
But I need to get something like Asia/Kolkata in return. For the access logs.
As said in the comments, you can only make a guess, but not have 100% sure.
I made some modifications to Chandra Nakka's function.
It will validate the guess with the timezone_identifiers_list() function, if it's not a valid timezone, the default will be returned.
function set_timezone_by_client_location($ip = NULL, $deep_detect = TRUE) {
$output = NULL;
if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
$ip = $_SERVER["REMOTE_ADDR"];
if ($deep_detect) {
if (filter_var(#$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
if (filter_var(#$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
}
$continents = array(
"AF" => "Africa",
"AN" => "Antarctica",
"AS" => "Asia",
"EU" => "Europe",
"OC" => "Australia",
"NA" => "America",
"SA" => "America"
);
$timezone = null;
if (filter_var($ip, FILTER_VALIDATE_IP)) {
$ipdat = #json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
if (#strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
$timezone = #$continents[strtoupper($ipdat->geoplugin_continentCode)] . '/' . #$ipdat->geoplugin_regionName;
$timezone = str_replace(' ', '_', $timezone);
}
}
if(!in_array($timezone, timezone_identifiers_list())){
$timezone = date_default_timezone_get();
}
return $timezone;
}
$timezone = set_timezone_by_client_location();
echo $timezone;
Framework: Laravel 7.x
namespace App\Services;
class TimeZoneService
{
/**
* Protected Variables
*/
protected $host = null;
protected $filter = null;
protected $ip = null;
protected $json = null;
public function __construct($ip, $filter = false)
{
$this->ip = $ip;
$this->filter = $filter;
$this->host = "http://www.geoplugin.net/json.gp?ip={$ip}";
}
/**
* fetch the location data via given IP address
*
* #return array
*/
public function getData()
{
if(function_exists('curl_init'))
{
# use cURL to fetch data
$request = curl_init();
# setting options
curl_setopt($request, CURLOPT_URL, $this->host);
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($request, CURLOPT_USERAGENT, 'geoPlugin PHP Class v1.1');
# response
$this->json = curl_exec($request);
# closing cURL
curl_close($request);
}
else if (ini_get('allow_url_fopen'))
{
# fall back to fopen()
$this->json = file_get_contents($this->host, 'r');
}
else
{
trigger_error('geoPlugin Error: Cannot retrieve data.', E_USER_ERROR);
return;
}
# returning
return $this;
}
/**
* convert the json string to php array
* based on the filter property
*
* #return array
*/
public function toArray()
{
# condition(s)
if($this->filter != true)
{
return json_decode($this->json, true);
}
# filtering & returning
return $this->__filter();
}
/**
* convert the json string to php object
* based on the filter property
*
* #return object
*/
public function toObject()
{
# condition(s)
if($this->filter != true)
{
return json_decode($this->json);
}
# filtering & returning
return (object)$this->__filter();
}
/**
* return collected location data in the form of json
* based on the filter property
*
* #return string
*/
public function toJson()
{
# condition(s)
if($this->filter != true)
{
return $this->json;
}
# filtering & returning
return json_encode($this->__filter());
}
/**
* filter the object keys
*
* #return array
*/
private function __filter()
{
# applying filter
foreach(json_decode($this->json, true) as $key => $item)
{
$return[str_replace('geoplugin_', '', $key)] = $item;
}
# returning
return $return;
}
}
SomeController.php
/**
* Services
*/
use App\Services\TimeZoneService;
class SomeController extends Controller
{
public function someMethod()
{
# services
$TimeZone = new TimeZoneService(<string IP_ADDRESS>, <boolean FILTER>);
$locationData = $TimeZone->getData()->toJson();
# OR
$locationData = $TimeZone->getData()->toArray();
# OR
$locationData = $TimeZone->getData()->toObject();
...
}
}
This code is working fine for me. However, If you see any room for improvement then please feel free to update the code to help others.
Thank you.

I am having an issue with the twig template system

I have opencart 3 installed on my dev box and have suddenly started getting the following error:
Fatal error: Class Twig_Loader_Filesystem contains 2 abstract methods
and must therefore be declared abstract or implement the remaining
methods (Twig_LoaderInterface::isFresh,
Twig_ExistsLoaderInterface::exists) in
/mnt/c/wsl/server/opencart/system/library/template/Twig/Loader/Filesystem.php
on line 17
I have been working on a custom template and all was going fine until I changed something in the controller of the footer. Changing it back did not resolve the issue. I have also manually cleared the cache in the OC folder and the twig folder. I also did not have the cache setting set to off so I manually made this change in the db as I get the same error trying to get into the admin.
I am at a loss. I would love any help I could get.
Call Stack
{main}( )
start( )
require_once( '/mnt/c/wsl/server/opencart/system/framework.php' )
Router->dispatch( )
Router->execute( )
Action->execute( )
ControllerStartupRouter->index( )
Action->execute( )
ControllerCommonHome->index( )
Loader->controller( )
Action->execute( )
ControllerCommonColumnLeft->index( )
Loader->view( )
Template->render( )
Template\Twig->render( )
spl_autoload_call ( )
Twig_Autoloader::autoload( )
require( '/mnt/c/wsl/server/opencart/system/library/template/Twig/Loader/Filesystem.php'
)
Location
.../index.php:0
.../index.php:19
.../startup.php:104
.../framework.php:165
.../router.php:56
.../router.php:67
.../action.php:79
.../router.php:25
.../action.php:79
.../home.php:12
.../loader.php:48
.../action.php:79
.../column_left.php:72
.../loader.php:125
.../template.php:51
.../twig.php:20
.../twig.php:20
.../Autoloader.php:51
class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
{
/** Identifier of the main namespace. */
const MAIN_NAMESPACE = '__main__';
protected $paths = array();
protected $cache = array();
protected $errorCache = array();
/**
* Constructor.
*
* #param string|array $paths A path or an array of paths where to look for templates
*/
public function __construct($paths = array())
{
if ($paths) {
$this->setPaths($paths);
}
}
/**
* Returns the paths to the templates.
*
* #param string $namespace A path namespace
*
* #return array The array of paths where to look for templates
*/
public function getPaths($namespace = self::MAIN_NAMESPACE)
{
return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array();
}
/**
* Returns the path namespaces.
*
* The main namespace is always defined.
*
* #return array The array of defined namespaces
*/
public function getNamespaces()
{
return array_keys($this->paths);
}
/**
* Sets the paths where templates are stored.
*
* #param string|array $paths A path or an array of paths where to look for templates
* #param string $namespace A path namespace
*/
public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
{
if (!is_array($paths)) {
$paths = array($paths);
}
$this->paths[$namespace] = array();
foreach ($paths as $path) {
$this->addPath($path, $namespace);
}
}
/**
* Adds a path where templates are stored.
*
* #param string $path A path where to look for templates
* #param string $namespace A path name
*
* #throws Twig_Error_Loader
*/
public function addPath($path, $namespace = self::MAIN_NAMESPACE)
{
// invalidate the cache
$this->cache = $this->errorCache = array();
if (!is_dir($path)) {
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
}
$this->paths[$namespace][] = rtrim($path, '/\\');
}
/**
* Prepends a path where templates are stored.
*
* #param string $path A path where to look for templates
* #param string $namespace A path name
*
* #throws Twig_Error_Loader
*/
public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
{
// invalidate the cache
$this->cache = $this->errorCache = array();
if (!is_dir($path)) {
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
}
$path = rtrim($path, '/\\');
if (!isset($this->paths[$namespace])) {
$this->paths[$namespace][] = $path;
} else {
array_unshift($this->paths[$namespace], $path);
}
}
/**
* {#inheritdoc}
*/
public function getSource($name)
{
return file_get_contents($this->findTemplate($name));
}
/**
* {#inheritdoc}
*/
public function getCacheKey($name)
{
return $this->findTemplate($name);
}
/**
* {#inheritdoc}
*/
public function exists($name)
{
$name = $this->normalizeName($name);
if (isset($this->cache[$name])) {
return true;
}
try {
return false !== $this->findTemplate($name, false);
} catch (Twig_Error_Loader $exception) {
return false;
}
}
/**
* {#inheritdoc}
*/
public function isFresh($name, $time)
{
return filemtime($this->findTemplate($name)) <= $time;
}
protected function findTemplate($name)
{
$throw = func_num_args() > 1 ? func_get_arg(1) : true;
$name = $this->normalizeName($name);
if (isset($this->cache[$name])) {
return $this->cache[$name];
}
if (isset($this->errorCache[$name])) {
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
$this->validateName($name);
list($namespace, $shortname) = $this->parseName($name);
if (!isset($this->paths[$namespace])) {
$this->errorCache[$name] = sprintf('There are no registered paths for namespace "%s".', $namespace);
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
foreach ($this->paths[$namespace] as $path) {
if (is_file($path.'/'.$shortname)) {
if (false !== $realpath = realpath($path.'/'.$shortname)) {
return $this->cache[$name] = $realpath;
}
return $this->cache[$name] = $path.'/'.$shortname;
}
}
$this->errorCache[$name] = sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]));
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
protected function parseName($name, $default = self::MAIN_NAMESPACE)
{
if (isset($name[0]) && '#' == $name[0]) {
if (false === $pos = strpos($name, '/')) {
throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "#namespace/template_name").', $name));
}
$namespace = substr($name, 1, $pos - 1);
$shortname = substr($name, $pos + 1);
return array($namespace, $shortname);
}
return array($default, $name);
}
protected function normalizeName($name)
{
return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
}
protected function validateName($name)
{
if (false !== strpos($name, "\0")) {
throw new Twig_Error_Loader('A template name cannot contain NUL bytes.');
}
$name = ltrim($name, '/');
$parts = explode('/', $name);
$level = 0;
foreach ($parts as $part) {
if ('..' === $part) {
--$level;
} elseif ('.' !== $part) {
++$level;
}
if ($level < 0) {
throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
}
}
}
}

Symfony - DateTime as param

I have trouble defining my datetime param with Symfony.
I am trying to return null if last_scan_date is null
and if not to return results!
Error says:
Argument 2 passed to checkLastScan() must be an instance of DateTime, string given
My function:
public function checkLastScan($hash, \DateTime $lastScanDate)
{
$findLastScan = $this->getMyRepository()->findOneBy([
'hash' => $hash,
'lastScanDate' => $lastScanDate
]);
if (!$findLastScan) {
throw new \Exception('Not found!');
}
if ($lastScanDate === null) {
return null;
} else {
return $findLastScan;
}
}
and my call:
$this->requirePostParams(['hash', 'last_scan_date']);
$this->container->get('app')->checkLastScan(
$this->data['hash'],
$this->data['last_scan_date']
);
return $this->success();
And enitity:
/**
* #ORM\Column(name="last_scan_date", type="date", nullable=true)
*/
private $lastScanDate;
Maybe problem is when requiring post params like:
/**
* Require post params
*
* #param $params
*/
protected function requirePostParams($params)
{
$currentRequest = $this->get('request_stack')->getCurrentRequest();
$postData = $currentRequest->request->all();
$postContent = json_decode($currentRequest->getContent(), true);
if (!empty($postContent)) {
$postData = $postContent;
}
$this->data = $postData;
$missingParams = [];
foreach ($params as $param) {
if (!array_key_exists($param, $postData)) {
$missingParams[] = $param;
}
}
If $this->data (I asked at first but you did not answer to me properly) is just the POST array, of course all members of the array are treated as string.
You have to parse last_scan_date string and transform it to DateTime type.
Here is the code of the function (change the value of YOUR_POST_FORMAT to the format you use in your HTML form):
/**
* Require post params
*
* #param $params
*/
protected function requirePostParams($params)
{
$currentRequest = $this->get('request_stack')->getCurrentRequest();
$postData = $currentRequest->request->all();
$postContent = json_decode($currentRequest->getContent(), true);
if (!empty($postContent)) {
$postData = $postContent;
}
// HERE YOU PARSE STRING TO DATETIME TYPE
if (isset($postData['last_scan_date']) && !empty($postData['last_scan_date'])) {
$postData['last_scan_date'] = DateTime::createFromFormat('YOUR POST FORMAT', $postData['last_scan_date'])
} else {
$postData['last_scan_date'] = null;
}
$this->data = $postData;
$missingParams = [];
foreach ($params as $param) {
if (!array_key_exists($param, $postData)) {
$missingParams[] = $param;
}
}
}

PHP MVC "route not found"

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'";
}
*/
?>

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

Categories