Komunikat o błędzie Surowe standardy: Metoda niestatyczna nie powinna być wywoływana statycznie w php

114

Mam następujący plik php. Jednak gdy widzę plik index.php, pojawia się następujący komunikat o błędzie.

Ścisłe standardy: Metoda niestatyczna Page :: getInstanceByName () nie powinna być wywoływana statycznie w /var/www/webworks/index.php w linii 12

Mam nadzieję, że ktoś może mi powiedzieć, jak rozwiązać problem.

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];
    }
piszczel
źródło
15
Hmm, czy to możliwe, że wywołujesz metodę statycznie, a ta metoda nie jest zdefiniowana jako statyczna? Wiesz, prawie dokładnie, co mówi błąd, w numerze linii jest napisane ...
Harold1983-

Odpowiedzi:

189

W Twoich metodach brakuje staticsłowa kluczowego . Zmiana

function getInstanceByName($name=''){

do

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

jeśli chcesz zadzwonić do nich statycznie.

Zauważ, że metody statyczne (i Singletony ) są śmiertelne dla testowalności .

Zauważ również, że wykonujesz zbyt dużo pracy w konstruktorze, zwłaszcza że nie powinno tam być całego zapytania. Wszystko, co powinien zrobić twój konstruktor, to ustawić obiekt w prawidłowym stanie. Jeśli musisz mieć dane spoza klasy, aby to zrobić, rozważ wstrzyknięcie ich zamiast pobierania. Pamiętaj również, że konstruktorzy nie mogą niczego zwrócić. Będą zawsze zwracane jako nieważne, więc wszystkie te return falsestwierdzenia tylko kończą konstrukcję.

Gordon
źródło
2
Kody pochodzą z tej książki ... packtpub.com/cms-design-using-php-and-jquery/book . Myślę, że powinieneś napisać książkę, Gordon. :-)
shin
5
@shin Nie, powtórzę tylko to, co inni powiedzieli lepiej niż ja wcześniej. Ale to naprawdę zły kod dla książki wydanej w grudniu 2010 roku. Czy podają jakiś powód do pominięcia słów kluczowych widoczności lub niestosowania się do konwencji kodowania PEAR? Miejmy nadzieję, że jQuery i ogólna architektura CMS są solidniejsze.
Gordon,
17
@dzona, która ignorowałaby problemy z kodem, a nie naprawiała go.
Gordon
1
Ważna uwaga: publicsłowo kluczowe jest używane tylko w deklaracjach funkcji / zmiennych z klasy. Zobacz stackoverflow.com/questions/13341378/…
cssyphus,
1
@Gordon, po prostu zaciekawiony - dlaczego opowiadasz się za zmianą obraźliwej metody na staticzamiast (ponownego) pisania kodu do użycia $p = new Page(); $p->getInstanceByName();?
Dennis
21

Myślę, że to może odpowiedzieć na twoje pytanie.

Metoda niestatyczna ..... nie powinna być wywoływana statycznie

Jeśli metoda nie jest statyczna, musisz ją zainicjować w następujący sposób:

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

Lub w PHP 5.4+ możesz użyć następującej składni:

(new ClassName)->method();
Groszek
źródło
Is (new ClassName) -> metoda (); kompatybilny również z PHP 5.3?
Jeff
1
@Jeff, użyłbym (new ClassName())->method();i uważam, że jest kompatybilny z PHP od 5 do 7
Dennis
1
(new ClassName)->method();nie jest kompatybilny z PHP 5.3. Właśnie tego spróbowałem.
Sonny
1

Spróbuj tego:

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

U mnie zadziałało w podobnym przypadku.

Andrés Frías
źródło
1

użyj className-> function (); zamiast className :: function ();

ulas korpe
źródło
0

return falsema zwykle na celu przerwanie tworzenia obiektu niepowodzeniem. To takie proste.

Tomas
źródło
0

Jeśli rozdzielczość zakresu :: musiała zostać użyta poza klasą, wówczas odpowiednia funkcja lub zmienna powinna być zadeklarowana jako statyczna

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
źródło
1
Czy możesz podać przykłady dla PO i wszystkich przyszłych odwiedzających?
B001 ᛦ
<? php class Foo {/ * Zmienna statyczna * / public static $ static_var = 'zmienna statyczna'; / * Funkcja statyczna * / Funkcja statyczna staticValue () {return 'funkcja statyczna'; } / * function * / function Value () {return 'Object'; }} echo Foo :: $ static_var. „<br/>”; echo Foo :: staticValue (). „<br/>”; $ foo = new Foo (); echo $ foo-> Wartość (); / * Mam nadzieję, że ten przykład pomoże ci * /
Ravi Krishnan
-1

Zamiast używać instancji z operatorem rozpoznawania zakresu :: ponieważ nie została zdefiniowana jako funkcja statyczna.

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

zmień to na:

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

I będzie działać jak urok.

Lorand
źródło