Bonjour,

Depuis peu je me suis remis à développer après plusieurs années sans pratique, et j'ai voulu me mettre à jour en m'initiant aux structures MVC. J'ai donc suivi le tutoriel de A à Z et je me confronte à cette erreur :

Warning: require(/www/deconuts/controller/Controller.php): failed to open stream: No such file or directory in /www/deconuts/core/Dispatcher.php on line 74 Fatal error: require(): Failed opening required '/www/deconuts/controller/Controller.php' (include_path='.:/usr/share/php') in /www/deconuts/core/Dispatcher.php on line 74

Or la ligne d'erreur correspond à la fonction LoadController à la ligne d'inclusion du controller :

function loadController()
    {
        $name = ucfirst($this->request->controller) . 'Controller';
        $file = ROOT . DS . 'controller' . DS . $name . '.php';
        require($file); // Ligne 74
        return new $name($this->request);
    }

Comme s'il n'incluait pas le nom du controller. Quelqu'un aurait une idée ?

Merci par avance :)

13 réponses


Carouge10
Réponse acceptée

Bonjour,

à la fin d'un foreach c'est : et ;

<?php foreach($pages as $p): ?>

Bonsoir,

Vous essayez d'ouvrir le fichier "Controller.php" dans le dossier "controller" et ce fichier n'existe pas, ce qui est logique.
Apparement "$this->request->controller" est vide.

Regarder du coté du router.
Pourrais-je avoir le code de la fonction parse du router ?

Merci

Bonjour,

Après moultes vérifications et moultes recherches, je ne trouve pas mon erreur. Même avec les codes premium j'ai un soucis. Après de nombreuses tentatives et les codes d'origine j'obtiens ceci :

Warning: require(/customers/9/2/e/alexandre-ribes.fr/httpd.www/deconutsitems/controller/DeconutsitemsController.php): failed to open stream: No such file or directory in /customers/9/2/e/alexandre-ribes.fr/httpd.www/deconutsitems/core/Dispatcher.php on line 39 Fatal error: require(): Failed opening required '/customers/9/2/e/alexandre-ribes.fr/httpd.www/deconutsitems/controller/DeconutsitemsController.php' (include_path='.:/usr/share/php') in /customers/9/2/e/alexandre-ribes.fr/httpd.www/deconutsitems/core/Dispatcher.php on line 39

Voici pour le routeur (celui du tuto donc) :

<?php
class Router{

    /**
    * Permet de parser une url
    * @param $url Url à parser
    * @return tableau contenant les paramètres
    **/
    static function parse($url,$request){
        $url = trim($url,'/'); 
        $params = explode('/',$url); 
        $request->controller = $params[0];
        $request->action = isset($params[1]) ? $params[1] : 'index';
        $request->params = array_slice($params,2);
        return true; 
    }
}

Le soucis étant je pense qu'il est impossible de se servir du site s'il n'est pas à la racine du dossier. L'erreur viendrait donc peut être du Request. je vais regarder ça :)

En utilisant la classe fournie par iriven je tombe sur une nouvelle erreur :

Warning: require(/customers/9/2/e/alexandre-ribes.fr/httpd.www/deconutsitems/controller/Http:Controller.php): failed to open stream: No such file or directory in /customers/9/2/e/alexandre-ribes.fr/httpd.www/deconutsitems/core/Dispatcher.php on line 39 Fatal error: require(): Failed opening required '/customers/9/2/e/alexandre-ribes.fr/httpd.www/deconutsitems/controller/Http:Controller.php' (include_path='.:/usr/share/php') in /customers/9/2/e/alexandre-ribes.fr/httpd.www/deconutsitems/core/Dispatcher.php on line 39

Il faudrait donc faire en sorte de rajouter une condition dans le loadcontroller pour l'index et ça devrait être bon du coup, en revanche quand je me mets dans le dossier pages j'ai une erreur surprenante :/

No input file specified.

Avec les fichiers du tutos je précise.

Bonjour,

function loadController() {
        $name = ucfirst($this->request->controller).'Controller';
        $file = ROOT.DS.'controller'.DS.$name.'.php';
        if(!file_exists($file)) {
            $this->error("Le controller ".$this->request->controller." n'existe pas.");
        }
        require($file);
        $controller = new $name($this->request);
        return $controller;
    }

Cordialement.

Oui mais le soucis c'est que le controller existe ;)

Bonjour, pourrez-je avoir le code de cette page qui bloque ?

Cordialement.

PS: Modifier la fonction du Router (Parse) par ceci (pour tester) :

static function parse($url, $request) {
        $url = trim($url, '/');
        if(empty($url)) {
            $url = Router::$routes[0]'url'];
        } else {
            $match = false;
            foreach(Router::$routes as $v) {
                if(!$match && preg_match($v'redirreg'], $url, $match)) {
                    $url = $v'origin'];

                    foreach($match as $k => $v) {
                        $url = str_replace(':'.$k.':', $v, $url);
                    }
                    $match = true;
                }
            }
        }
        $params = explode('/', $url);
        if(in_array($params[0], array_keys(self::$prefixes))) {
            $request->prefix = self::$prefixes$params[0]];
            array_shift($params);
        }
        $request->controller = $params[0];
        $request->action = isset($params[1]) ? $params[1] : 'index';

        foreach(self::$prefixes as $k => $v) {
            if(strpos($request->action, $v.'_') === 0) {
                $request->prefix = $v;
                $request->action = str_replace($v.'_', '', $request->action);
            }
        }
        $request->params = array_slice($params, 2);
        return true;
    }

Cordialement.

Du coup j'ai une erreur dans le routeur :

<?php
class Router
{

    /**
    * Permet de parser une url
    * @param $url Url à parser
    * @return tableau contenant les paramètres
    **/
    static function parse($url, $request) 
    {
        $url = trim($url, '/');

        if(empty($url)) 
        {
            $url = Router::$routes[0]'url'];
        } 
        else 
        {
            $match = false;

            foreach(Router::$routes as $v) 
            {
                if(!$match && preg_match($v'redirreg'], $url, $match)) 
                {
                    $url = $v'origin'];

                    foreach($match as $k => $v) 
                    {
                        $url = str_replace(':'.$k.':', $v, $url);
                    }

                    $match = true;
                }
            }
        }

        $params = explode('/', $url);

        if(in_array($params[0], array_keys(self::$prefixes))) 
        {
            $request->prefix = self::$prefixes$params[0]];
            array_shift($params);
        }

        $request->controller = $params[0];
        $request->action = isset($params[1]) ? $params[1] : 'index';

        foreach(self::$prefixes as $k => $v) 
        {
            if(strpos($request->action, $v.'_') === 0) 
            {
                $request->prefix = $v;
                $request->action = str_replace($v.'_', '', $request->action);
            }
        }

        $request->params = array_slice($params, 2);
        return true;
    }
}

Fatal error: Access to undeclared static property: Router::$routes in /customers/9/2/e/alexandre-ribes.fr/httpd.www/deconutsitems/core/Router.php on line 21

Sinon voici les autres fichiers :

Controller.php

<?php 
/**
* Controller
**/
class Controller{

    public $request; // Objet Request 
    private $vars = array();    // Variables à passer à la vue
    public $layout = 'default'; // Layout à utiliser pour rendre la vue
    private $rendered = false; // Si le rendu a été fait ou pas ?
    /*
    **  Constructeur
    **  ------------
    **  @request :: objet request de notre application
    */
    function __construct($request)
    {
        //  On stocke la requête dans l'instance
        $this->request = $request;  
    }
    /*
    **  Permet de retourner une vue
    **  ------------
    **  @view :: fichier à rendre (chemin depuis view ou nom de la vue)
    */
    public function render($view)
    {
        if($this->rendered)
        { 
            return false; 
        }
        extract($this->vars); 
        if(strpos($view,'/')===0)
        {
            $view = ROOT.DS.'view'.$view.'.php';
        }
        else
        {
            $view = ROOT.DS.'view'.DS.$this->request->controller.DS.$view.'.php';
        }
        ob_start(); 
        require($view);
        $content_for_layout = ob_get_clean();  
        require(ROOT.DS.'view'.DS.'layout'.DS.$this->layout.'.php'); 
        $this->rendered = true; 
    }

    /**
    * Permet de passer une ou plusieurs variable à la vue
    * @param $key nom de la variable OU tableau de variables
    * @param $value Valeur de la variable
    **/
    /*
    **  Permet de passer une ou plusieurs variables à la vue
    **  ------------
    **  @key :: nom de la variable, ou tableau de variable
    **  @value :: valeur de la variable (si une seule variable)
    */
    public function set($key, $value = NULL)
    {
        if(is_array($key))
        {
            $this->vars += $key; 
        }
        else
        {
            $this->vars$key] = $value; 
        }
    }
    /*
    **  Permet de charger un model
    **  ------------
    **  @name :: nom du modèle
    */
    function loadModel($name)
    {
        if(!isset($this->$name))
        {
            $file = ROOT.DS.'model'.DS.$name.'.php'; 
            require_once($file);
            $this->$name = new $name(); 
        }
    }
    /**
    * Permet de gérer les erreurs 404
    **/
    /*
    **  Permet de gérer les erreurs 404
    **  ------------
    **  @message :: message de l'erreur 404
    */
    function e404($message)
    {   
        header("HTTP/1.0 404 Not Found");
        $this->set('message',$message); 
        $this->render('/errors/404');
        die();
    }
}
?>

Dispatcher.php

<?php
/*
**  @core/Dispatcher.php
**  ------------
**  Permet de charger le controller en fonction de la requête utilisateur
*/
class Dispatcher{

    //  Objet reçu
    var $request;   
    /*
    **  Constructeur du dispatcher
    **  Charge le controller en fonction du routing
    */
    function __construct()
    {
        $this->request = new Request(); 
        Router::parse($this->request->url, $this->request); 
        $controller = $this->loadController();
        if(!in_array($this->request->action , get_class_methods($controller)) )
        {
            $this->error('Le controller "' . $this->request->controller . '"" n\'a pas de méthode "' . $this->request->action . '"'); 
        }
        call_user_func_array(array($controller,$this->request->action), $this->request->params); 
        $controller->render($this->request->action);
    }
    /*
    **  Permet de générer une page d'erreur en cas d'un problème au niveau du rooting
    */
    function error($message)
    {
        $controller = new Controller($this->request); 
        $controller->e404($message); 
    }
    /*
    **  Permet de générer un message avec un titre
    */
    function info($title, $message)
    {
        $controller = new Controller($this->request);
        $controller->set(array(
            'title' =>  $title,
            'message'   =>  $message,
        ));
        // $this->render->('/errors/info');
    }
    /*
    **  Permet de charger le controller en fonction de la requête utilisateur
    */
    function loadController()
    {
        if( $this->request->controller == 'Http:')
        {
            $name = ucfirst($this->request->controller).'Controller'; 
        }
        else
        {
            $name = 'PagesController';
        }
        $file = ROOT.DS.'controller'.DS.$name.'.php'; 
        require($file); 
        return new $name($this->request);  
    }
}

Request.php

<?php
class Request
{
    public $url; 
    public $page = 1;
    public $prefix = FALSE;
    public $Getdata = FALSE;
    public $Postdata = FALSE;
    public function __construct()
    {
        header('Expires: Mon, 12 Dec 1982 06:14:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: no-cache, must-revalidate, max-age=0');
        header('Pragma: no-cache');
        $this->url = strlen($this->pathInfo())? $this->pathInfo() : $this->BaseUrl();
        if(!empty($_POST)) $this->Postdata = $_POST;     
        if(!empty($_GET)) $this->Getdata = $_GET;
        if(isset($this->Getdata->page)and is_numeric($this->Getdata->page) and($this->Getdata->page > 0)) $this->page = round($this->Getdata->page);
    }

    private function pathInfo()
    {
        if (strlen(getenv('PATH_INFO')) > 1) return rtrim(getenv('PATH_INFO'),'/\\');
        if( array_key_exists('PATH_INFO', $_SERVER) and strlen($_SERVER'PATH_INFO']) ) return rtrim($_SERVER'PATH_INFO'], '/\\');
        if( array_key_exists('ORIG_PATH_INFO', $_SERVER) and strlen($_SERVER'ORIG_PATH_INFO']) ) return rtrim($_SERVER'ORIG_PATH_INFO'], '/\\');
        return rtrim(str_replace($this->BaseUrl(), '', current(explode('?',$this->Uri()))), '/\\'); 
     }           
    public function Domain()
    {
        if(isset($_SERVER'HTTP_HOST']))
        {
            if(preg_match('/(localhost|127\.0\.0\.1)/', $_SERVER'HTTP_HOST']) || $_SERVER'SERVER_ADDR'] == '127.0.0.1')
            {
                return NULL; 
            }
            $host = strtolower( htmlentities(strip_tags((string) $_SERVER'HTTP_HOST'])));
            return preg_replace('/(^www\.|:\d+$)/i', NULL, $host);
        }
        if(isset($_SERVER'SERVER_NAME']))
        {
            $host = strtolower( htmlentities(strip_tags((string) $_SERVER'SERVER_NAME'])));
            return preg_replace('/(^www\.|:\d+$)/i', NULL, $host);
        }
        return NULL;
    }
    private function Uri() 
    {    
        if( !array_key_exists('REQUEST_URI', $_SERVER) or !strlen($_SERVER'REQUEST_URI'])) 
        {
            if (isset($_SERVER'HTTP_X_REWRITE_URL'])) 
            {
                $uri = $_SERVER'HTTP_X_REWRITE_URL'];
            }
            else
            {
                $uri = BaseUrl();
            }
            if($_SERVER'QUERY_STRING']) $uri .= '?' . $_SERVER'QUERY_STRING'];
            {
                $uri = filter_var($uri, FILTER_SANITIZE_URL);
            }
        }
        else
        {
            $uri = filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL);
        }

        if (($uri == '/') || ($uri == '\\')) $uri .= basename(filter_input(INPUT_SERVER, 'PHP_SELF', FILTER_SANITIZE_URL));

            if ((strtolower(substr($uri, -4)) == '.ico') || (strtolower(substr($uri, -4)) == '.png') || (strtolower(substr($uri, -4)) == '.gif') || (strtolower(substr($uri, -4)) == '.jpg'))
                return '';

            if ($uri == '') return '';
            $uri = str_replace($this->Scheme(), ':#:', $uri);
            $uri = str_replace(DS, '/', $uri);
            $uri = str_replace(':#:', $this->Scheme(), $uri);
        return rtrim($uri, '/\\');
    }   
    public function Referrer()
    {
        return ( ! isset($_SERVER'HTTP_REFERER']) OR $_SERVER'HTTP_REFERER'] == '') ? '' : trim($_SERVER'HTTP_REFERER']);
    }

    public function Url() 
    {
        $url = rtrim($this->BaseUrl(), '/').'/'.ltrim($this->pathInfo(),'/');
        return rtrim($url, '/\\');
    } 
    public function BaseUrl() 
    {
        $url = $this->Scheme().(($this->ServerPort() !== '') ?($this->Domain().':'.$this->ServerPort()) : $this->Domain());
        return rtrim($url, '/\\');
    } 
    private function isHttps()
    {
        return (bool)(isset($_SERVER'HTTPS']) && ($_SERVER'HTTPS'] == 'on' || $_SERVER'HTTPS'] === TRUE)) ? TRUE : FALSE ;
    }
    private function Scheme()
    { 
        $Scheme = 'http';
        return $Scheme .=($this->isHttps() === TRUE) ? 's://':'://' ;
    }

    private function ServerPort()
    {
        return (($_SERVER'SERVER_PORT'] != 80 &&
                !($this->isHttps())) ||
                ($_SERVER'SERVER_PORT'] != 443 &&
                ( $this->isHttps() == true))) ?
                (int)$_SERVER'SERVER_PORT'] : '';
    }   
}

Model.php

<?php
class Model
{

    static $connections = array(); 
    public $conf = 'default';
    public $table = false; 
    public $db; 
    public function __construct()
    {
        // Connexion à la base de donnée
        $conf = Conf::$databases$this->conf];
        if(isset(Model::$connections$this->conf]))
        {
            $this->db = Model::$connections$this->conf];
            return true; 
        }
        try{
            $pdo = new PDO(
                'mysql:host='.$conf'host'].';dbname='.$conf'database'].';',
                $conf'login'],
                $conf'password'],
                array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8')
            );
            $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
            Model::$connections$this->conf] = $pdo; 
            $this->db = $pdo; 
        }catch(PDOException $e){
            if(Conf::$debug >= 1)
            {
                die($e->getMessage()); 
            }
            else
            {
                die('Impossible de se connecter à la base de donnée'); 
            }
        }

        // Initialisation de quelques variables
        if($this->table === false)
        {
            $this->table = strtolower(get_class($this)).'s'; 
        }
    }
    /*
    **  Fonction de recherche
    */
    public function find($req)
    {
        $sql = 'SELECT * FROM '.$this->table.' as '.get_class($this).' ';

        // Construction de la condition
        if(isset($req'conditions']))
        {
            $sql .= 'WHERE ';
            if(!is_array($req'conditions']))
            {
                $sql .= $req'conditions']; 
            }
            else
            {
                $cond = array(); 
                foreach($req'conditions'] as $k=>$v)
                {
                    if(!is_numeric($v))
                    {
                        $v = '"'.mysql_escape_string($v).'"'; 
                    }

                    $cond] = "$k=$v";
                }
                $sql .= implode(' AND ',$cond);
            }
        }
        $pre = $this->db->prepare($sql); 
        $pre->execute(); 
        return $pre->fetchAll(PDO::FETCH_OBJ); 
    }
    public function findFirst($req)
    {
        return current($this->find($req)); 
    }
}

L'erreur est listée plus haut. Sinon j'ai toujours le soucis de "No Input File Selected"

Je suis dessus depuis hier soir et personnellement je ne comprends pas :/

Si quelqu'un pourrait éclairer mes lumières

Bonjour, tenter ce router :

<?php
Class Router {
    static $routes = array();
    static $prefixes = array();
    static function prefix($url, $prefix) {
        self::$prefixes$url] = $prefix;
    }
    static function parse($url, $request) {
        $url = trim($url, '/');
        if(empty($url)) {
            $url = Router::$routes[0]'url'];
        } else {
            $match = false;
            foreach(Router::$routes as $v) {
                if(!$match && preg_match($v'redirreg'], $url, $match)) {
                    $url = $v'origin'];

                    foreach($match as $k => $v) {
                        $url = str_replace(':'.$k.':', $v, $url);
                    }
                    $match = true;
                }
            }
        }
        $params = explode('/', $url);
        if(in_array($params[0], array_keys(self::$prefixes))) {
            $request->prefix = self::$prefixes$params[0]];
            array_shift($params);
        }
        $request->controller = $params[0];
        $request->action = isset($params[1]) ? $params[1] : 'index';

        foreach(self::$prefixes as $k => $v) {
            if(strpos($request->action, $v.'_') === 0) {
                $request->prefix = $v;
                $request->action = str_replace($v.'_', '', $request->action);
            }
        }
        $request->params = array_slice($params, 2);
        return true;
    }
    static function connect($redir, $url) {
        $r = array();
        $r'params'] = array();
        $r'url'] = $url;
        $r'originreg'] = preg_replace('/([a-z0-9]+):(^\/]+)/', '${1}:(?P<${1}>${2})', $url);
        $r'originreg'] = str_replace('/*', '(?P<args>/?.*)', $r'originreg']);
        $r'originreg'] = '/^'.str_replace('/', '\/', $r'originreg']).'$/';
        $r'origin'] = preg_replace('/([a-z0-9]+):(^\/]+)/', ':${1}:', $url);
        $r'origin'] = str_replace('/*', ':args:', $r'origin']);
        $params = explode('/', $url);
        foreach($params as $k => $v) {
            if(strpos($v, ':')) {
                $p = explode(':', $v);
                $r'params']$p[0]] = $p[1];
            }
        }
        $r'redirreg'] = $redir;
        $r'redirreg'] = str_replace('/*', '(?P<args>/?.*)', $r'redirreg']);
        foreach($r'params'] as $k => $v) {
            $r'redirreg'] = str_replace(":$k", "(?P<$k>$v)", $r'redirreg']);
        }
        $r'redirreg'] = '/^'.str_replace('/', '\/', $r'redirreg']).'$/';
        $r'redir'] = preg_replace('/:([a-z0-9]+)/', ':${1}:', $redir);
        $r'redir'] = str_replace('/*', ':args:', $r'redir']);
        self::$routes] = $r;
    }
    static function url($url = '') {
        trim($url, '/');
        foreach(self::$routes as $v) {
            if(preg_match($v'originreg'], $url, $match)) {
                $url = $v'redir'];
                foreach($match as $k => $w) {
                    $url = str_replace(":$k:", $w, $url);
                }
            }
        }
        foreach(self::$prefixes as $k => $v) {
            if(strpos($url, $v) === 0) {
                $url = str_replace($v, $k, $url);
            }
        }
        return BASE_URL.'/'.$url;
    }
    static function webroot($url) {
        trim($url, '/');
        return BASE_URL.'/'.$url;
    }
}

Cordialement.

Super ça marche, en revanche j'ai toujours une erreur. Le résultat de la page d'index est :

Parse error: syntax error, unexpected T_ENDFOREACH in /customers/9/2/e/alexandre-ribes.fr/httpd.www/deconutsitems/view/layout/default.php on line 17

et toujours "No input file selected" dès que je veux rentrer dans la vue deconutsitems/pages/

Voici le layout :

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> 
    <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
    <title><?php echo isset($title_for_layout)?$title_for_layout:'Mon site'; ?></title> 
    <link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap-1.2.0.min.css">
    </head> 
    <body>       

        <div class="topbar"> 
          <div class="topbar-inner"> 
            <div class="container"> 
              <h3><a href="#">Mon site</a></h3> 
              <ul class="nav"> 
                <?php foreach($pages as $p); ?>
                    <li><a href="<?php echo BASE_URL.'/pages/view/'.$p->id; ?>" title="<?php echo $p->name; ?>"><?php echo $p->name; ?></a></li> 
                <?php endforeach; ?>
              </ul>
            </div> 
          </div> 
        </div> 

        <div class="container" style="padding-top:60px;">
            <?php echo $content_for_layout; ?>
        </div>

    </body> 
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
</html>

Forcément -_-

J'ai ceci comme erreur du coup en revanche.

Warning: Invalid argument supplied for foreach() in /customers/9/2/e/alexandre-ribes.fr/httpd.www/deconutsitems/view/layout/default.php on line 15

Je vais reprendre le code en profondeur parce qu'à force de chercher les erreurs je commence à ne plus rien voir et c'est usant :/

Je suis en train de suivre ce tuto aussi et le $pages se transforme en $pagesMenu.

Essayer de faire un

<?php var_dump($pages); ?>

et/ou avec $pagesMenu pour savoir s'il n'est pas vide.

Je vais me débrouiller autrement pour le moment, c'est pour un projet assez urgent donc je vais faire au plus simple ;)

Merci de vos réponses dans tous les cas :)