Message d'erreur Normes strictes: la méthode non statique ne doit pas être appelée statiquement en php

114

J'ai le php suivant. Cependant, lorsque je vois l'index.php, j'obtiens le message d'erreur suivant.

Normes strictes: La méthode non statique Page :: getInstanceByName () ne doit pas être appelée statiquement dans /var/www/webworks/index.php à la ligne 12

J'espère que quelqu'un pourra me dire comment résoudre le problème.

index.php

// { common variables and functions
include_once('ww.incs/common.php');
$page=isset($_REQUEST['page'])?$_REQUEST['page']:'';
$id=isset($_REQUEST['id'])?(int)$_REQUEST['id']:0;
...

// { get current page id
if(!$id){
    if($page){ // load by name
        $r=Page::getInstanceByName($page);
        if($r && isset($r->id))$id=$r->id;
    }
    if(!$id){ // else load by special
        $special=1;
        if(!$page){
            $r=Page::getInstanceBySpecial($special);
            if($r && isset($r->id))$id=$r->id;
        }
    }
}

// { load page data
if($id){
    $PAGEDATA=(isset($r) && $r)?$r : Page::getInstance($id);
}
else{
    echo '404 thing goes here';
    exit;
}
...
...

ww.incs / common.php

<?php
require dirname(__FILE__).'/basics.php';
...
...

ww.incs / basics.php

session_start();
if(!function_exists('__autoload')){
    function __autoload($name) {
        require $name . '.php';
    }
}
...
...

Page.php

class Page{
    static $instances             = array();
    static $instancesByName     = array();
    static $instancesBySpecial   = array();
    function __construct($v,$byField=0,$fromRow=0,$pvq=0){
        # byField: 0=ID; 1=Name; 3=special
        if (!$byField && is_numeric($v)){ // by ID
            $r=$fromRow?$fromRow:($v?dbRow("select * from pages where id=$v limit 1"):array());
        }
        else if ($byField == 1){ // by name
            $name=strtolower(str_replace('-','_',$v));
            $fname='page_by_name_'.md5($name);
            $r=dbRow("select * from pages where name like '".addslashes($name)."' limit 1");
        }
        else if ($byField == 3 && is_numeric($v)){ // by special
            $fname='page_by_special_'.$v;
            $r=dbRow("select * from pages where special&$v limit 1");
        }
        else return false;
        if(!count($r || !is_array($r)))return false;
        if(!isset($r['id']))$r['id']=0;
        if(!isset($r['type']))$r['type']=0;
        if(!isset($r['special']))$r['special']=0;
        if(!isset($r['name']))$r['name']='NO NAME SUPPLIED';
        foreach ($r as $k=>$v) $this->{$k}=$v;
        $this->urlname=$r['name'];
        $this->dbVals=$r;
        self::$instances[$this->id] =& $this;
        self::$instancesByName[preg_replace('/[^a-z0-9]/','-',strtolower($this->urlname))] =& $this;
        self::$instancesBySpecial[$this->special] =& $this;
        if(!$this->vars)$this->vars='{}';
        $this->vars=json_decode($this->vars);
    }
    function getInstance($id=0,$fromRow=false,$pvq=false){
        if (!is_numeric($id)) return false;
        if (!@array_key_exists($id,self::$instances)) self::$instances[$id]=new Page($id,0,$fromRow,$pvq);
        return self::$instances[$id];
    }
    function getInstanceByName($name=''){
        $name=strtolower($name);
        $nameIndex=preg_replace('#[^a-z0-9/]#','-',$name);
        if(@array_key_exists($nameIndex,self::$instancesByName))return self::$instancesByName[$nameIndex];
        self::$instancesByName[$nameIndex]=new Page($name,1);
        return self::$instancesByName[$nameIndex];
    }
    function getInstanceBySpecial($sp=0){
        if (!is_numeric($sp)) return false;
        if (!@array_key_exists($sp,$instancesBySpecial)) $instancesBySpecial[$sp]=new Page($sp,3);
        return $instancesBySpecial[$sp];
    }
tibia
la source
15
Hmm, est-ce que vous appelez une méthode de manière statique et que cette méthode n'est pas définie comme statique? Vous savez, à peu près exactement ce que dit l'erreur, sur le numéro de ligne, il dit ...
Harold1983-

Réponses:

189

Vos méthodes manquent le staticmot - clé . Changement

function getInstanceByName($name=''){

à

public static function getInstanceByName($name=''){

si vous souhaitez les appeler de manière statique.

Notez que les méthodes statiques (et les singletons ) sont mortelles pour la testabilité .

Notez également que vous faites beaucoup trop de travail dans le constructeur, en particulier tout ce que les requêtes ne devraient pas être là. Tout ce que votre constructeur est censé faire est de mettre l'objet dans un état valide. Si vous devez avoir des données extérieures à la classe pour le faire, pensez à les injecter au lieu de les extraire. Notez également que les constructeurs ne peuvent rien renvoyer. Ils retourneront toujours nul, donc toutes ces return falsedéclarations ne font rien d'autre que mettre fin à la construction.

Gordon
la source
2
Les codes sont tirés de ce livre ... packtpub.com/cms-design-using-php-and-jquery/book . Je pense que tu devrais écrire un livre, Gordon. :-)
shin
5
@shin Nah, je ne ferais que répéter ce que les autres ont dit mieux que moi auparavant. Mais c'est un très mauvais code pour un livre sorti en décembre 2010. Est-ce qu'ils donnent une raison pour omettre des mots-clés de visibilité ou ne pas suivre la convention de codage PEAR? Espérons que l'architecture jQuery et générale du CMS est plus solide.
Gordon
17
@dzona qui ignorerait les problèmes avec le code, pas le réparerait.
Gordon
1
REMARQUE importante: le publicmot-clé est utilisé uniquement dans les déclarations de fonction / variable à partir d'une classe. Voir stackoverflow.com/questions/13341378/…
cssyphus
1
@Gordon, juste curieux - pourquoi préconisez-vous de changer la méthode incriminée au staticlieu de (ré) écrire le code à utiliser $p = new Page(); $p->getInstanceByName();?
Dennis
21

Je pense que cela peut répondre à votre question.

La méthode non statique ..... ne doit pas être appelée statiquement

Si la méthode n'est pas statique, vous devez l'initialiser comme ceci:

$var = new ClassName();
$var->method();

Ou, dans PHP 5.4+, vous pouvez utiliser cette syntaxe:

(new ClassName)->method();
Pois
la source
Is (nouveau nom de classe) -> method (); compatible avec PHP 5.3 aussi?
Jeff
1
@Jeff, j'utiliserais (new ClassName())->method();, et je crois qu'il est compatible avec PHP de 5 à 7
Dennis
1
(new ClassName)->method();n'est pas compatible avec PHP 5.3. J'ai juste essayé.
Sonny
1

Essaye ça:

$r = Page()->getInstanceByName($page);

Cela a fonctionné pour moi dans un cas similaire.

Andrés Frías
la source
1

utilisez className-> function (); à la place className :: function ();

ulas korpe
la source
0

return falseest généralement destiné à terminer la création de l'objet avec un échec. C'est aussi simple que ça.

Tomas
la source
0

Si la résolution de portée :: devait être utilisée en dehors de la classe, la fonction ou la variable respective devrait être déclarée comme statique

class Foo { 
        //Static variable 
        public static $static_var = 'static variable'; 
        //Static function 
        static function staticValue() { return 'static function'; } 

        //function 
        function Value() { return 'Object'; } 
} 



 echo Foo::$static_var . "<br/>"; echo Foo::staticValue(). "<br/>"; $foo = new Foo(); echo $foo->Value();
Ravi Krishnan
la source
1
Pouvez-vous donner des exemples pour le PO et tous les futurs visiteurs?
B001 ᛦ
<? php class Foo {/ * Variable statique * / public static $ static_var = 'variable statique'; / * Fonction statique * / fonction statique staticValue () {return 'fonction statique'; } / * function * / function Value () {return 'Object'; }} echo Foo :: $ static_var. "<br/>"; echo Foo :: staticValue (). "<br/>"; $ toto = nouveau toto (); echo $ foo-> Value (); / * J'espère que cet exemple vous aidera * /
Ravi Krishnan
-1

Au lieu d'utiliser l'instance avec l'opérateur de résolution de portée :: car elle n'a pas été définie comme une fonction statique.

$r=Page::getInstanceByName($page);

changez-le en:

$r=Page->getInstanceByName($page);

Et cela fonctionnera comme un charme.

Lorand
la source