Trying to get property of non-object

Par Noudnou, il y a 12 ans


Bonjour )à tous,
j'ai un souci avec mon code pourtant je vois vraiment pas d'où viens l'erreur. Je n'arrive pas a appeler une variable d'une autre classe alors que celle ci est public ...

<?php
class PostsController extends Controller
{
    private $perPage = 1;
    public function view($id = null)
    {
        $this->loadmodel('Post');
        $conditions = array('id' => $id, 'online' => 1, 'type' => 'post');
        $d'post'] = $this->Post->findFirst(array(
            'conditions' => $conditions
            ));
        $this->set($d);
        if(empty($d'post']))
            $this->e404('Page introuvable');
        $this->set($d);
    }

    public function postsMenu()
    {
        var_dump($this->request);
        $this->loadmodel('Post');
        $conditions = array('online' => 1, 'type' => 'post');
        return $this->Post->find(array(
            'conditions' => $conditions,
            'limit' => $this->perPage*$this->request->page.','.$this->perPage
            ));
    }
    public function pagination()
    {
        $this->loadmodel('Post');
        $conditions = array('online' => 1, 'type' => 'post');
        $d'total'] = $this->Post->findCount($conditions);
        return $d'page'] = ceil($d'total'] / $this->perPage);
    }

}

Le problème viens de cette ligne là : 'limit' => $this->perPage*$this->request->page.','.$this->perPage

<?php
class Controller
{
    public $request;
    private $vars = array();
    public $layout = 'default';
    private $rendered = false;
    public function __construct($request = null)
    {
        $this->request = $request;
    }
    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;
    }
    public function set($key, $value = null)
    {
        if(is_array($key))
        {
            $this->vars += $key;
        }
        else
        {
            $this->vars$key] = $value;
        }
    }
    public function loadmodel($name)
    {
        $file = ROOT.DS.'model'.DS.$name.'.php';
        require_once($file);
        if(!isset($this->$name))
            $this->$name = new $name();
    }
    /**
     * Permet de gérer les erreurs 404
     */

    function e404($message)
    {
        $this->set('message_error', $message);
        $this->render('/errors/404');
    }
    public function request($controller, $action)
    {
        $controller .='Controller';
        require_once ROOT.DS.'controller'.DS.$controller.'.php';
        $c = new $controller();
        return $c->$action();
    }
    static function cut_content($content, $nb)
    {
        return $content = substr($content, 0, $nb);
    }
}

<?php
class Request
{
    public $url; // URL Appelé
    public $page = 1;
    function __construct()
    {
        $this->url = $_SERVER'PATH_INFO'];
        if(isset($_GET'page']))
            if(is_numeric($_GET'page']))
                if($_GET'page'] > 0)
                    $this->page = round($_GET'page']);
    }
}

J'ai déjà cherché, mais je trouve vraiment pas ...
Si vous aviez une idée !
Merci !

15 réponses

Noudnou, il y a 12 ans

Ouais c'est pas facile, j'ai moi même du mal à tout comprendre, alors je re-re-regarde les tutos, pour bien comprendre ce qu'y m'a échapper et j'arrive petit à petit à comprendre les choses. Mais là j'avoue être tombé sur un drôle de souci, j'avais déjà cherché avec quelques membres du channel #Grafikart, ils n'ont pas su trouver, non plus.
Je sais vraiment pas d'où l'erreur peu venir :/
En plus ce qui est curieux, quand j'essaye de faire un var_dump($this->request->page) depuis ma fonction PostMenu, il me met : Trying to get property of non-object. Hors, la variable de la classe Request étant publique est accessible partout. De plus j'instancie ma classe Request dans mon dispatcher via la variable $request. Je pense donc que c'est bon ...

Lorsque je fais : var_dump($this->request), il me sort bien le résultat (soit celui de la Classe Request).
Mais si je rajoute le page derrière, il n'aime pas :/

Vallyan, il y a 12 ans

fait un var_dump($this);var_dump($this->request);

Vallyan, il y a 12 ans

var_dump de la variable qui est supposée etre un objet, aussi ...

Noudnou, il y a 12 ans

L'erreur est celle du titre, je vous ais aussi indiqué le code défectueux, c'est ligne 29 du Controller.
Le problème viens de request, qui lorsque l'on effectue un var_dump() dessus depuis la fonction postsMenu retourne null.
Et je ne comprends pas pourquoi, la variable est instancié bien comme il faut, la variable $page est bien public, bref un mystère !
C'est comme si il n'arrivait pas à trouver la variable $page :/
Voila voila !

Vallyan, il y a 12 ans
// Ligne 67 de Controller:
return $c->$action();
           ^-- en trop :P
Vallyan, il y a 12 ans
$c = new $controller();
         ^ ca aussi d'ailleurs c'est en trop il me semble
Noudnou, il y a 12 ans

Quand j'enlève ces deux lignes, il m'indique qu'il y a des erreurs au niveau de mon foreach dans mon layout :
Invalid argument supplied for foreach()

EDIT : Pour moi return $c->action() permettait de renvoyer les valeurs en fonction du controller ...

Vallyan, il y a 12 ans

evidemment ! c'est les $ qu'il faut enlever !

Vallyan, il y a 12 ans

si tu utilises new, c'est un nom de classe a mettre après. Donc pas de $, et c'est case-sensitive (donc Controller a priori, et pas $controller)

Noudnou, il y a 12 ans

Non ce ne sont pas les $ qu'il faut enlever, car :

public function request($controller, $action)
    {
        $controller .='Controller';
        require_once ROOT.DS.'controller'.DS.$controller.'.php';
        $c = new $controller();
        return $c->$action();
    }

$c est une instance de la variable controller (C'est une manière dynamique d'instancier PostsController ou PagesController)
Et du coup, ce que l'on veut retourner c'est le la variable $action de ce controller.

Vallyan, il y a 12 ans

AAAAhhhhh oups -__-' ...

Noudnou, il y a 12 ans

var_dump($this) me donne cela :

object(PostsController)[6]
private 'perPage' => int 1
public 'request' => null
private 'vars' (Controller) =>
array (size=0)
empty
public 'layout' => string 'default' (length=7)
private 'rendered' (Controller) => boolean false

et var_dump($this->request) : null

C'est peut être le fait qu'il y ait null avant la variable $page qu'il n'aime pas ?

Vallyan, il y a 12 ans

quand tu fais ceci:

$this->request->page

, tu utilises la variable $request de ta classe, pas la fonction request() ... c'est pas ca le problème ? Parce que c'est la fonction qui retourne un objet ...

Vallyan, il y a 12 ans

ET: si tu remplace par request(), oublie pas de lui fournir les arguments.

Noudnou, il y a 12 ans

Dans mon controller je veux la variable request, pas la fonction. Je veux ça :

public function __construct($request = null)
    {
        $this->request = $request;
    }

Après longue discut' sur le chat IRC, j'ai réussi à comprendre mon erreur. Le problème viens, lors de mon instance de classe Controller, je dois lui transmettre les variables de ma classe Request. Je dois passer de cela :

public function request($controller, $action)
    {
        $controller .='Controller';
        require_once ROOT.DS.'controller'.DS.$controller.'.php';
        $c = new $controller();
        return $c->$action();
    }

à cela :

public function request($controller, $action)
    {
        $controller .='Controller';
        require_once ROOT.DS.'controller'.DS.$controller.'.php';
        $c = new $controller($this->request->page);
        return $c->$action();
    }

Comme ça ensuite je peux récupérer la valeur de la variable page ;)