fetal error: path not found - php

Hi Guys I'm working on a MVC based php application.In my include.php which is also in the server root of my server has following codes in order to fetch model and controller automatically from Controller folder inside the application directory of the server root.
My project directory is like this
accountBook
|-Application
| |-Controller
| | |-IndexController.php
| | |-baseController.php
| |_-Model
|-Content
|-index.php
|-config.php
|-includes.php
<?php
/*
*#Package Name: accountBook/includes.php
*#Date(Last Modified): Thru, Sept 15 - 2016
*#Author: Ajax Hill
*/
namespace accountBook
{
use accountBook\Application\Controller;
class accessControl
{
private $args,$type,$nature;
private static function route()
{
define('DS',DIRECTORY_SEPARATOR);
define('ROOT',getcwd().DS);
define('CONF', ROOT.'config.php');
include_once(CONF);
$con= new PDO;
if($result=$con->query('SELECT theme from sys_def'))
{
while($row=$result->fetch(PDO::FETCH_ASSOC))
{
define('THEME_NAME',$row['theme']);
}
}
else
{
echo "ERROR: Could not execute".print_r($pdo->errorInfo());
}
/*
* #var THEME_NAME(view) has been Fetch from Database
*/
define('CONTENT', ROOT.'content'.DS);
define('THEME_PATH',CONTENT.'themes'.DS.THEME_NAME.DS);
define('APP',ROOT.'Application'.DS);
define('CONTROL_PATH',APP.'contollers'.DS);
define('MODEL_PATH',APP.'models'.DS);
// index.php?p=admin&c=Goods&a=add
define("PLATFORM", isset($_REQUEST['p']) ? $_REQUEST['p'] : 'home');
define("CONTROLLER", isset($_REQUEST['c']) ? $_REQUEST['c'] : 'Index');
define("ACTION", isset($_REQUEST['a']) ? $_REQUEST['a'] : 'index');
unset($con);
}
// Autoloading
private static function autoload()
{
// Controller
require_once CONTROL_PATH. "{$classname}.php";
}
elseif (substr($classname, -5) == "Model")
{
// Model
require_once MODEL_PATH . "{$classname}.php";
}
}
// Routing and dispatching
private static function dispatch()
{
// Instantiate the controller class and call its action method
$controller_name = CONTROLLER . "Controller";
$action_name = ACTION . "Action";
$controller = new $controller_name;
$controller->$action_name();
}
public function __construct($type, $args,$nature='show')
/**
* var #type has two values = account | toDo
* var #type is post title
* var #nature is to determine the nature
*/
{
$this->args=$args;
$this->type=$type;
$this->nature=$nature;
self::route();
self::autoload();
self::dispatch();
}
}
}
Now I've create IndexController.php in Application folder
<?php
/**
*#Package Name: accountBook/Application/Controller/IndexController.php
*#Date(Last Modified): Thru, Sept 15 - 2016
*#Author: Ajax Hill
*/
namespace accountBook\Application\controller;
class IndexController extends baseController
{
public function mainAction(){
include THEME_PATH. "main.html";
// Load Captcha class
$this->loader->library("Captcha");
$captcha = new Captcha;
$captcha->hello();
$userModel = new UserModel("user");
$users = $userModel->getUsers();
}
public function indexAction(){
$userModel = new UserModel("user");
$users = $userModel->getUsers();
// Load View template
include THEME_PATH . "index.php";
}
public function menuAction(){
include THEME_PATH . "menu.php";
}
public function dragAction(){
include THEME_PATH . "drag.php";
}
public function topAction(){
include THEME_PATH . "top.php";
}
}
When Loading index file which has included includes.php I'm getting Following error
fetal error at line 67 not found path c://phpproj/accountBook/Application/Controller/accountBook/Application/Controller/baseController.php
Now Please help me adjust so that baseController fetch from c://phpproj/accountBook/Application/Controller/baseController.php

Your Class should have read something like:
<?php
/*
*#Package Name: accountBook/includes.php
*#Date(Last Modified): Thru, Sept 15 - 2016
*#Author: Ajax Hill
*/
namespace accountBook;
use accountBook\Application\Controller;
class accessControl {
private $args,$type,$nature;
private static function route(){
define('DS',DIRECTORY_SEPARATOR);
define('ROOT',getcwd().DS);
define('CONF', ROOT.'config.php');
include_once(CONF);
$con= new PDO;
if($result=$con->query('SELECT theme from sys_def')) {
while($row=$result->fetch(PDO::FETCH_ASSOC)){
define('THEME_NAME',$row['theme']);
}
}else{
echo "ERROR: Could not execute".print_r($pdo->errorInfo());
}
/*
* #var THEME_NAME(view) has been Fetch from Database
*/
define('CONTENT', ROOT.'content'.DS);
define('THEME_PATH',CONTENT.'themes'.DS.THEME_NAME.DS);
define('APP',ROOT.'Application'.DS);
define('CONTROL_PATH',APP.'contollers'.DS);
define('MODEL_PATH',APP.'models'.DS);
// index.php?p=admin&c=Goods&a=add
define("PLATFORM", isset($_REQUEST['p']) ? $_REQUEST['p'] : 'home');
define("CONTROLLER", isset($_REQUEST['c']) ? $_REQUEST['c'] : 'Index');
define("ACTION", isset($_REQUEST['a']) ? $_REQUEST['a'] : 'index');
unset($con);
}
// Autoloading
private static function autoload(){
$classname = algorithm_2_get_className();
if(substr($classname, -10) == "Controller"){
// Controller
$classFile = CONTROL_PATH . "{$classname}.php";
}else if (substr($classname, -5) == "Model"){
// Model
$classFile = MODEL_PATH . "{$classname}.php";
}
if(file_exists($classFile){
require_once $classFile;
}else{
// HANDLE FILE-NOT FOUND EXCEPTION...
}
}
// Routing and dispatching
private static function dispatch(){
// Instantiate the controller class and call its action method
$controller_name = CONTROLLER . "Controller";
$action_name = ACTION . "Action";
$controller = new $controller_name;
$controller->$action_name();
}
public function __construct($type, $args,$nature='show'){
/**
* var #type has two values = account | toDo
* var #type is post title
* var #nature is to determine the nature
*/
$this->args=$args;
$this->type=$type;
$this->nature=$nature;
self::route();
self::autoload();
self::dispatch();
}
}

Related

How to use namespace properly in PHP?

I have this file root/core/Router.php
<?php
namespace Core;
class Router {
protected $url;
protected $controller;
private function parseURL() {
// threat the $this->url; for example ["r", "product"]
}
private function request() {
$this->controller = Controller::get($this->url[1]);
}
public function __construct() {
$this->parseURL();
$this->request();
}
}
?>
then file root/core/Controller.php
<?php
namespace Core;
class Controller {
public static function model($name, $params = []) {
$model = "\\Model\\$name";
return new $model($params);
}
public static function view($name, $params = []) {
require_once APP_DIR . "view/" . $name . ".php";
}
public static function get($name, $params = []) {
require_once APP_DIR . "controller/" . $name . ".php";
$name = "\\Controller\\$name";
return new $name($params);
}
}
?>
then root/controler/Product.php
<?php
namespace Controller;
use Core\Controller;
use Model\Product;
class Product {
public function get() {
$ret['state'] = 510;
$productModel = new Product;
$products = $productModel->getAll();
if(isset($products)) {
$ret['products'] = $products;
$ret['state'] = 200;
}
return $ret;
}
}
?>
then file root/model/Product.php
<?php
namespace Model;
class Product {
public function add($values) {
return Database::insert("product", $values);
}
}
?>
and root/core/Model.php
<?php
namespace Core;
class Model {
protected $table = null;
public function getAll() {
// some code to collect data
}
}
?>
What i want to achive is that every Controller in root/controller/*.php able to load any Model in root/model/*.php but class inside root/model/*.php must able to access (inheritance/extends) the Model class inside root/core/Model.php i firstly asked on chatGPT for some AI Generated answer, that the reason why i get this far.
Then i get this error, when the AI keep giving the same answer.
Fatal error: Cannot declare class Controller\Product because the name is already in use in C:\xampp\htdocs\app\shop\controller\Product.php on line 6
I actually realize that the simple way probably with naming the class so ther no conflict between it but i became aware how to properly using the namespace if its such features in php. Those files loaded without any autoloader, so i just require_once each file in root/init.php file.
I read few documentations but hard to implement in multiple files and directorys.
I Apreciate any feedback, thanks

Cannot declare class ABC, because the name is already in use

Here am getting an error like Fatal error: Cannot declare class ABC, because the name is already in use in while listing all controller names and functions in project.In order to get i got an library from surroundings and placed it.library looks like this
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
/***
* File: (Codeigniterapp)/libraries/Controllerlist.php
*
* A simple library to list al your controllers with their methods.
* This library will return an array with controllers and methods
*
* The library will scan the "controller" directory and (in case of) one (1) subdirectory level deep
* for controllers
*
* Usage in one of your controllers:
*
* $this->load->library('controllerlist');
* print_r($this->controllerlist->getControllers());
*
* #author Peter Prins
*/
class ControllerList {
/**
* Codeigniter reference
*/
private $CI;
/**
* Array that will hold the controller names and methods
*/
private $aControllers;
// Construct
function __construct() {
// Get Codeigniter instance
$this->CI = get_instance();
// Get all controllers
$this->setControllers();
}
/**
* Return all controllers and their methods
* #return array
*/
public function getControllers() {
return $this->aControllers;
}
/**
* Set the array holding the controller name and methods
*/
public function setControllerMethods($p_sControllerName, $p_aControllerMethods) {
$this->aControllers[$p_sControllerName] = $p_aControllerMethods;
}
/**
* Search and set controller and methods.
*/
private function setControllers() {
// Loop through the controller directory
foreach(glob(APPPATH . 'controllers/*') as $controller) {
// if the value in the loop is a directory loop through that directory
if(is_dir($controller)) {
// Get name of directory
$dirname = basename($controller, 'EXT');
// Loop through the subdirectory
foreach(glob(APPPATH . 'controllers/'.$dirname.'/*') as $subdircontroller) {
// Get the name of the subdir
$subdircontrollername = basename($subdircontroller, EXT);
// Load the controller file in memory if it's not load already
if(!class_exists($subdircontrollername)) {
$this->CI->load->file($subdircontroller);
}
// Add the controllername to the array with its methods
$aMethods = get_class_methods($subdircontrollername);
$aUserMethods = array();
foreach($aMethods as $method) {
if($method != '__construct' && $method != 'get_instance' && $method != $subdircontrollername) {
$aUserMethods[] = $method;
}
}
$this->setControllerMethods($subdircontrollername, $aUserMethods);
}
}
else if(pathinfo($controller, PATHINFO_EXTENSION) == "php"){
// value is no directory get controller name
$controllername = basename($controller, 'EXT');
// Load the class in memory (if it's not loaded already)
if(!class_exists($controllername)) {
var_dump($controller);
$this->CI->load->file($controller);
}
// Add controller and methods to the array
$aMethods = get_class_methods($controllername);
//var_dump($aMethods);
$aUserMethods = array();
if(is_array($aMethods)){
foreach($aMethods as $method) {
if($method != '__construct' && $method != 'get_instance' && $method != $controllername) {
$aUserMethods[] = $method;
}
}
}
$this->setControllerMethods($controllername, $aUserMethods);
}
}
}
}
// EOF
Here am getting error in the line $this->CI->load->file($controller);.when i call this library in my controller am getting error what i mentioned in title.Is it a problem of php version,Here it is telling that controller class name is already called so it cannot be call again.

How to combine routing and templating?

So, I've created a webshop system. It all worked perfectly, except for that projects can always be improved. So someone told me that 'Templating' and 'Routing' would be nice improvements. I've written classes for both of them, and they work fine! Now, I do wish to know how to combine them? How can I combine these classes so that data from the routing (to determine the content) needs to be placed inside the template. How would I do this?
Templating class:
class Template
{
private $assignedValues = array();
private $tpl;
/*
** #description Creates one single instance of itself and checks whether the template file exists.
** #param $path [string] This is the path to the template
*/
public function __construct($_path = '')
{
if(!empty($_path)){
if(file_exists($_path)){
$this->tpl = file_get_contents($_path);
}
else{
echo '<b>Template Error:</b> File Inclusion Error.';
}
}
}
/*
** #description Assign a value to a part in the template.
** #param $_searchString [string] This is the part in the template that needs to be replaced
** #param $_replaceString [string] This is the code/text that will replace the part in the template
*/
public function assign($_searchString, $_replaceString)
{
if(!empty($_searchString)){
$this->assignedValues[strtoupper($_searchString)] = $_replaceString;
}
}
/*
** #description Shows the final result of the page.
*/
public function show()
{
if(count($this->assignedValues > 0)){
foreach ($this->assignedValues as $key => $value) {
$this->tpl = str_replace('{'.$key.'}', $value, $this->tpl);
}
}
echo $this->tpl;
}
/*
** #description Quickly load a part of the page
** #param $quickLoad [string] This is the name of the file that will be loaded and assigned
** #param $_searchString [string] This is the part in the template that needs to be replaced
*/
public function quickLoad($_searchString, $part)
{
if(file_exists(INCLUDES.DS.$part.'.php')){
$this->assign($_searchString,include(INCLUDES.DS.$part.'.php'));
}
else{
return "That file does not exist!";
}
}
}
And the routing class:
class Route
{
protected $controller = 'App';
protected $method = 'Call';
protected $params = [];
/*
** #description Loads the classes and methods which are referred to.
*/
public function __construct()
{
$url = $this->parseUrl();
if($this->checkUrl())
{
unset($url[0]);
if(isset($url[1]))
{
if (file_exists('core/classes/' . $url[1] . '.class.php'))
{
$this->controller = $url[1];
unset($url[1]);
}
}
require_once('core/classes/' . $this->controller . '.class.php');
$this->controller = new $this->controller;
if (isset($url[2]))
{
if (method_exists($this->controller, $url[2]))
{
$this->method = $url[2];
unset($url[2]);
}
}
$this->params = $url ? array_values($url) : [];
$this->arrayUrl($this->params);
call_user_func_array([$this->controller, $this->method], $this->params);
}
}
/*
** #description Check whether the URL part contains a string
*/
public function checkUrl($index = '0',$value = 'Route'){
$url = $this->parseUrl();
if($url[$index] == $value){
return true;
}
return false;
}
/*
** #description Splits the url into pieces.
*/
protected function parseUrl()
{
if(isset($_GET['url']))
{
return $url = explode('/', filter_var(rtrim(urldecode($_GET['url']), '/'), FILTER_SANITIZE_URL));
}
}
/*
** #description Sets arrays in routes.
*/
protected function arrayUrl($params = array())
{
foreach($params as $index => $param)
{
if (preg_match('/>/',$param))
{
$newParam = explode('>', $param);
unset($this->params[$index]);
$this->params['fields'][$newParam[0]] = $newParam[1];
}
else{
unset($this->params[$index]);
$this->params[] = $param;
}
}
print_r($this->params);
}
}
I can access my routes by URL's like this:
http://localhost:8080/Webshop/Route/User/logout
With: Class & Method.
This is a simple example that I already use, because no data needs to be showed using this method. It only logs out the user that is logged in. After that, you get redirected to the home page. But how could I use routing for other pages? For example, update some user data without having to create an update file?
EDIT:
This is an example of a page I use now (index.php):
<?php
/*
** #description Includes config.php once so that we can use classes, defines etcetera.
*/
require_once('core/preferences/config.php');
/*
** #description Instanciate new route object.
*/
$route = new Route();
/*
** #description Check if a route isset. When not, continue, else: run route
*/
if(!$route->checkUrl())
{
/*
** #description Instanciate new template object.
*/
$template = new Template(TEMPLATES_PATH .'/camerashop24.tpl.html');
/*
** #description Assign values.
*/
$template->assign('title', 'Home');
$template->assign('root', '');
$template->quickLoad('loginout', 'loginout');
$template->quickLoad('title_block', 'title_block');
$template->quickLoad('cart','cart');
$template->quickLoad('menu', 'menu');
$template->assign('page', 'Home');
$breadcrumbs = new Breadcrumbs($_SERVER["REQUEST_URI"],'');
$template->assign('breadcrumbs', $breadcrumbs->data());
$content = "";
foreach(explode(",",Config::get('settings/front_page_cat')) as $item) {
$content .= "<div id='blue-box' class='blue-box'><h2 style='color: white;'>" . strtoupper($item) . "</h2></div>";
$category = new Category();
$category->find($item);
if($category->exists($item)){
foreach (explode(",",$category->data()->products) as $item) {
$product = new Product($item);
$product->find($item);
$content .= '' . $product->showProduct($product->data()->type,$product->data()->name,$product->data()->price) . '';
}
}
}
$template->assign('text', $content);
$template->quickLoad('footer','footer');
/*
** #description Showing content.
*/
$template->show();
}
But, what I want as an answer, how can I show the data from the routing (select users profile for example) in this template without having to create a page for it like this one.
I think you're gonna have to modify your Routing class. Ideally you want the routing class to give YOU the ability to tell it what controller the route should use. Th controller you select would act as the middle man for processing. Each controller's method would represent a route, something like this:
/**
* URL = www.test.com/index.php/home
* URL = www.test.com/index.php/about
*
* ROUTE Class:
* - should define routes. Example:
*
* $route["/home"] = MainController/home
* $route["/about"] = MainController/about
* $route["/*"] = MainController/*
*
*/
class MainController
{
public function home()
{
$template = new Template(TEMPLATES_PATH . 'home.tpl.html');
$template->show();
}
public function about()
{
$template = new Template(TEMPLATES_PATH . 'about.tpl.html');
$template->show();
}
}

PHP autoloader not working with namespaces

Its the first time working with an autoloader and getting some errors.
The structure is as follows:
AnimalShop (root)
classes
Shop.php
index.php
I have the following simple code
Index.php
<?php
spl_autoload_register(function ($class_name)
{
include $class_name . '.php';
});
echo "<h1>PETs SHOP</h1>";
// Create a shop
$shop = new Shop();
Shop is a simple class
<?php
namespace PHPAdvanced\AnimalShop\classes;
/*
* Pet shop
*/
class Shop
{
/**
* #var Pets[] pets
*/
private $pets = [];
public function addPetsToArray(Pets $pet)
{
$this->pets[] = $pet;
}
/**
* Print pets naam
*/
public function printPets()
{
foreach($this->pets as $pet)
{
echo "<p>" . $pet->getPetNaam() . "</p>";
}
}
}
When i run index.php i get the following errors:
Warning: include(Shop.php): failed to open stream: No such file or directory in /var/www/phpadvancedCourse/AnimalShop/index.php on line 4
Warning: include(): Failed opening 'Shop.php' for inclusion (include_path='.:/usr/share/php:') in /var/www/phpadvancedCourse/AnimalShop/index.php on line 4
spl_autoload_register(function ($class_name)
{
include realpath(dirname(__FILE__))."/classes/".$class_name . '.php';
});
your path is wrong.. try this..
To solve the problem i have used PSR-4 autoloading through composer with the following structure and code.
Structure
AnimalShop (root)
index.php
App (Folder)
Behavior (Folder)
WalkBehavior.php (interface)
Pets(Folder)
Cat.php
Dog.php
Fish.php
Pets.php (abstract class)
Shop(Folder)
PetShop.php
Composer.json
{
"autoload" : {
"psr-4" : {
"App\\" : "App"
}
}
}
index.php
<?php
// Autoload
require "vendor/autoload.php";
use App\Shop\PetShop;
use App\Pets\Dog;
use App\Pets\Fish;
use App\Pets\Cat;
echo "<h1>PETs SHOP</h1>";
// Create a shop
$shop = new PetShop();
$shop->addPetsToArray(new Dog("Yuki"));
$shop->addPetsToArray(new Fish("BLubie"));
$shop->addPetsToArray(new Cat("Cattie"));
$shop->printPets();
Example of Petshop and Dog
<?php
namespace App\Shop;
use App\Pets\Pets;
/*
* Pet shop
*/
class PetShop
{
/**
* #var Pets[] pets
*/
private $pets = [];
public function addPetsToArray(Pets $pet)
{
$this->pets[] = $pet;
}
/**
* Print pets naam
*/
public function printPets()
{
foreach($this->pets as $pet)
{
echo "<p>" . $pet->getPetNaam() . "</p>";
}
}
}
DOG
<?php
namespace App\Pets;
/**
* Class Dog
*/
class Dog extends Pets
{
/**
* Dog constructor.
*
* #param $name
*/
public function __construct(string $name)
{
parent::__construct($name);
}
public function walk() : string
{
return "Dog is walking";
}
}

Can you help me fix the exception/error message handling in my control architecture script?

Can you help me fix the exception/error message handling in my control architecture script?
First, let me post the actual script...
Note: some of the code's indentation is a bit off, but I am uncertain how to fix it. I apologize.
class FrontController extends ActionController {
//Declaring variable(s)
private static $instance;
protected $controller;
//Class construct method
public function __construct() {}
//Starts new instance of this class with a singleton pattern
public static function getInstance() {
if(!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function dispatch($throwExceptions = false) {
/* Checks for the GET variables $module and $action, and, if present,
* strips them down with a regular expression function with a white
* list of allowed characters, removing anything that is not a letter,
* number, underscore or hyphen.
*/
$regex = '/[^-_A-z0-9]+/';
$module = isset($_GET['module']) ? preg_replace($regex, '', $_GET['module']) : 'home';
$action = isset($_GET['action']) ? preg_replace($regex, '', $_GET['action']) : 'frontpage';
/* Generates Actions class filename (example: HomeActions) and path to
* that class (example: home/HomeActions.php), checks if $file is a
* valid file, and then, if so, requires that file.
*/
$class = ucfirst($module) . 'Actions';
$file = $this->pageDir . '/' . $module . '/' . $class . '.php';
if (!is_file($file)) {
throw new FrontControllerException('Page not found!');
}
require_once $file;
/* Creates a new instance of the Actions class (example: $controller
* = new HomeActions();), and passes the registry variable to the
* ActionController class.
*/
$controller = new $class();
$controller->setRegistry($this->registry);
try {
//Trys the setModule method in the ActionController class
$controller->setModule($module);
/* The ActionController dispatchAction method checks if the method
* exists, then runs the displayView function in the
* ActionController class.
*/
$controller->dispatchAction($action);
}
catch(Exception $error) {
/* An exception has occurred, and will be displayed if
* $throwExceptions is set to true.
*/
if($throwExceptions) {
echo $error->errorMessage($error); //Full exception echoed
} else {
echo $error->errorMessage(null); //Simple error messaged echoed
}
}
}
}
abstract class ActionController {
//Declaring variable(s)
protected $registry;
protected $module;
protected $registryItems = array();
//Class construct method
public function __construct(){}
public function setRegistry($registry) {
//Sets the registry object
$this->registry = $registry;
/* Once the registry is loaded, the controller root directory path is
* set from the registry. This path is needed for the controller
* classes to work properly.
*/
$this->setPageDir();
}
//Sets the controller root directory from the value stored in the registry
public function setPageDir() {
$this->pageDir = $this->registry->get('pageDir');
}
//Sets the module
public function setModule($module) {
$this->module = $module;
}
//Gets the module
public function getModule() {
return $this->module;
}
/* Checks for actionMethod in the Actions class (example: doFrontpage()
* within home/HomeActions.php) with the method_exists function and, if
* present, the actionMethod and displayView functions are executed.
*/
public function dispatchAction($action) {
$actionMethod = 'do' . ucfirst($action);
if (!method_exists($this, $actionMethod)) {
throw new FrontControllerException('Page not found!');
}
$this->$actionMethod();
$this->displayView($action);
}
public function displayView($action) {
if (!is_file($this->pageDir . '/' . $this->getModule() . '/' . $action . 'View.php')) {
throw new FrontControllerException('Page not found!');
}
//Sets $this->actionView to the path of the action View file
$this->actionView = $this->pageDir . '/' . $this->getModule() . '/' . $action . 'View.php';
//Sets path of the action View file into the registry
$this->registry->set('actionView', $this->actionView);
//Includes template file within which the action View file is included
require_once $this->pageDir . '/default.tpl';
}
}
class Registry {
//Declaring variables
private $store;
//Class constructor
public function __construct() {}
//Sets registry variable
public function set($label, $object) {
$this->store[$label] = $object;
}
//Gets registry variable
public function get($label) {
if(isset($this->store[$label])) {
return $this->store[$label];
}
return false;
}
//Adds outside array of registry values to $this->store array
public function addRegistryArray($registryItems) {
foreach ($registryItems as $key => $value) {
$this->set($key, $value);
}
}
//Returns registry array
public function getRegistryArray() {
return $this->store;
}
}
class FrontControllerException extends Exception {
public function errorMessage($error) {
//If throwExceptions is true, then the full exception is returned.
$errorMessage = isset($error) ? $error : $this->getMessage();
return $errorMessage;
}
}
Now, the problem... If I enter a URL with a nonexistent module (in the following example "BLAH")...
http://example.com/index.php?module=BLAH&action=frontpage
...I get not simply the error message "Page not found!" but the following error message...
Fatal error: Uncaught exception 'FrontControllerException' with message 'Page not found!' in /web/example.com/library/php/ControlArchitecture.php:45 Stack trace: #0 /web/example.com/index.php(30): FrontController->dispatch(false) #1 {main} thrown in /web/example.com/library/php/ControlArchitecture.php on line 45
Any ideas on why I do not simply get the "Page not found!" message (instead of the uncaught exception)? Any ideas on how to fix this behavior?
Thanks again!
The error message actually says it all.
Wether the FrontController->dispatch() methods argument is true or false the exception will be thrown anyway..(if there's some framework magic going on, please let us know which framework you're using)
So make sure you're catching the exception where you're calling it:
/* ... */
try {
FrontController->dispatch(false);
} catch (Exception $ex) {
echo "Eception caught: " . $ex.getMessage();
}
/* ... */
Update:
Here you can read about exceptions in PHP and how to catch them.
About the non-existent module issue:
$regex = '/[^-_A-z0-9]+/';
$module = isset($_GET['module']) ? preg_replace($regex, '', $_GET['module']) : 'home';
$action = isset($_GET['action']) ? preg_replace($regex, '', $_GET['action']) : 'frontpage';
$class = ucfirst($module) . 'Actions';
$file = $this->pageDir . '/' . $module . '/' . $class . '.php';
if (!is_file($file)) {
throw new FrontControllerException('Page not found!');
}
The IF-Statement only checks if the module file (Pattern: ModuleActions.php) in this case BLAHActions.php exists or not. Once it has thrown the exception, your call will the cancelled and it won't be processed anymore. (This means that it won't even continue to check the Action parameter)
About the non-existent action issue:
As of what I understand from the posted code, folowing method:
public function dispatchAction($action) {
$actionMethod = 'do' . ucfirst($action);
if (!method_exists($this, $actionMethod)) {
throw new FrontControllerException('Page not found!');
}
$this->$actionMethod();
$this->displayView($action);
}
makes calls to the required action (Pattern: doSomething) in this case doFrontPage isn't even called because your code throws an exception beforehand.
Calling a non existent action does not throw an unhandled exception, because it is handled in your FrontController->dispatch() method just after the module check:
try {
//Trys the setModule method in the ActionController class
$controller->setModule($module);
/* The ActionController dispatchAction method checks if the method
* exists, then runs the displayView function in the
* ActionController class.
*/
$controller->dispatchAction($action);
}
catch(Exception $error) {
/* An exception has occurred, and will be displayed if
* $throwExceptions is set to true.
*/
if($throwExceptions) {
echo $error->errorMessage($error); //Full exception echoed
} else {
echo $error->errorMessage(null); //Simple error messaged echoed
}
}

Categories