'Must be of the type array, null given,
I keep getting the following error and I'm not to sure why:
Catchable fatal error: Argument 3 passed to System\Loader::action() must be of the type array, null given, called in /Application.php on line 31 and defined in /Loader.php on line 18
Loader class:
<?php
namespace System;
class Loader{
//application object
private $app;
//controllers container of array
private $controllers = [];
//models container array
private $models = [];
//constructor takes in system/application $app
public function __construct(Application $app){
$this->app = $app;
}
//call the given controller with the given method and pass the given arguments to the controller method
//takes in string $controller, string $method and array $arguements returns mixed
public function action ($controller, $method, array $arguements){ ##line 18
$object = $this->controller($controller);
return call_user_func([$object, $method], $arguements);
}
//call the given controller takes in string $controller and returns object
public function controller ($controller){
$controller = $this->getControllerName($controller);
if(! $this->hasController($controller)){
$this->addController($controller);
}
return $this->getController($controller);
}
//determine if the given clas/controller exists in the controller container takes in string $controller and returns boolean
private function hasController($controller){
return array_key_exists($controller, $this->controllers);
}
//create new object for the given controller and store it in the controllers container
//takes in string $controller and returns void
private function addController($controller){
$object = new $controller($this->app);
$this->controllers[$controller] = $object;
}
//get the controller object takes in string $controller and returns object
private function getController($controller){
return $this->controllers[$controller];
}
//get the full class name for the given controller takes string $controller returns string
private function getControllerName($controller){
$controller .= 'Controller';
$controller = 'App\\Controllers\\' . $controller;
return str_replace('/', '\\', $controller);
}
//call the given Model takes in string $Model and returns object
public function model ($model){
$model = $this->getModelName($model);
if(! $this->hasModel($model)){
$this->addModel($model);
}
return $this->getModel($model);
}
//determine if the given clas/Model exists in the Model container takes in string $controller and returns boolean
private function hasModel($model){
return array_key_exists($model, $this->models);
}
//create new object for the given Model and store it in the controllers container
//takes in string $Model and returns void
private function addModel($model){
$object = new $model($this->app);
$this->models[$model] = $object;
}
//get the Model object takes in string $Model and returns object
private function getModel($model){
return $this->models[$model];
}
//get the full class name for the given Model takes string $Model returns string
private function getModelName($model){
$model .= 'Model';
$model = 'App\\Models\\' . $model;
return str_replace('/', '\\', $model);
}
}
application class:
<?php
namespace System;
class Application {
//Container array var
private $container = [];
//application object
private static $instance;
//constructor $file param
private function __construct(File $file){
$this->share('file', $file);
$this->registerClasses();
// static::$instance = $this;
$this->loadHelpers();
}
//get application instance parameter $file returns system\application
public static function getInstance($file = null){
if(is_null(static::$instance)) {
static::$instance = new static($file);
}
return static::$instance;
}
//run the application returns void
public function run(){
$this->session->start();
$this->request->prepareUrl();
$this->file->call('App/index.php');
list($controller, $method, $arguments) = $this->route->getProperRoute();
$output = (string) $this->load->action($controller, $method, $arguments); ##line 31
$this->response->setOutput($output);
$this->response->send();
}
//register classes in sql auto load register
private function registerClasses(){
spl_autoload_register([$this, 'load']);
}
//load class through autoloading takes string $class and returns void
public function load($class){
if(strpos($class, 'App') === 0){
$file = $class . '.php';
} else {
//get the class from vendor
$file = 'vendor/' . $class . '.php';
}
if($this->file->exists($file)){
$this->file->call($file);
}
}
//load helpers file returns void
private function loadHelpers(){
$this->file->call('vendor/helpers.php');
}
// get shared value takes in string $key returns mixed
public function get($key){
if(! $this->isSharing($key)){
if($this->isCoreAlias($key)){
$this->share($key, $this->createNewCoreObject($key));
} else{
die('<b>' . $key . '</br> not found in application container');
}
}
return $this->container[$key];
// return $this->isSharing() ? $this->container[$key] : null;
}
//determind if the given key is shared through application takes string $key returns boolean
public function isSharing($key){
return isset($this->container[$key]);
}
//share key and value through application
public function share($key, $value){
$this->container[$key] = $value;
}
//determines if the given key is an alias to core class takes string $alias returns boolean
public function isCoreAlias($alias){
$coreClasses = $this->coreClasses();
return isset($coreClasses[$alias]);
}
//create new object for the core class based on the given alias takes in string $alias returns object
public function createNewCoreObject($alias){
$coreClasses = $this->coreClasses();
$object = $coreClasses[$alias];
return new $object($this);
}
//get all core classes with its aliase returns array
private function coreClasses(){
return [
'request' => 'System\\Http\\Request',
'response' => 'System\\Http\\Response',
'session' => 'System\\Session',
'route' => 'System\\Route',
'cookie' => 'System\\Cookie',
'load' => 'System\\Loader',
'html' => 'System\\Html',
'db' => 'System\\Database',
'view' => 'System\\View\\ViewFactory',
'url' => 'System\\Url',
];
}
//get shared value dynamically takes string $key returns mixed
public function __get($key){
return $this->get($key);
}
}
Not too sure where its getting this null from would appreciate if someone could help me figure this out.
edit: route class
<?php
namespace System;
class Route {
//application object
private $app;
//routes container
private $routes = [];
//not found url
private $notFound;
//constructor
public function __construct(Application $app){
$this->app = $app;
}
//add new route takes string $url string $action and string $requestmethod returns void
public function add ($url, $action, $requestMethod = 'GET'){
$route = [
'url' => $url,
'pattern' => $this->generatePattern($url),
'action' => $this->getAction($action),
'method' => strtoupper($requestMethod),
];
$this->routes[] = $route;
}
//set not found url take string $url returns void
public function notFound($url){
$this->notFound = $url;
}
//get proper route reutns array
public function getProperRoute(){
foreach ($this->routes as $route) {
if ($this->isMatching($route['pattern'])){
$arguments = $this->getArgumentsFrom($route['pattern']);
list($controller, $method) = explode('@', $route['action']);
return [$controller, $method, $arguments];
}
}
}
//determine if the given pattern matches the current requested url takes string $pattern returns boolean
private function isMatching($pattern){
return preg_match($pattern, $this->app->request->url());
}
// get arguement from the current requested url based on the given pattern takes in string $pattern returns array
private function getArgumentsFrom($pattern){
preg_match($pattern, $this->app->request->url(), $matches);
array_shift($matches);
return $matches;
}
//generate a regex pattern for the given url takes string url returns string
private function generatePattern($url){
$pattern = '#^';
// :text ([a-zA-Z0-9-]+)
// :id (\d+)
$pattern .= str_replace([':text', ':id'], ['([a-zA-Z0-9-]+)', '(\d+)'], $url);
$pattern .= '$#';
return $pattern;
}
//get proper action takes in string $action returns string
private function getAction($action){
$action = str_replace('/', '\\', $action);
return strpos($action, '@') !== false ? $action : $action . '@index';
}
}
Solution 1:[1]
The call getProperRoute() is returning an array of 2 elements and this is why the "$arguements" is NULL.
You can either change the call to:
public function action ($controller, $method, array $arguements = []){
$object = $this->controller($controller);
return call_user_func([$object, $method], $arguements);
}
Or check what is the return of the getProperRoute Method
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Thomas Goik |