Mensaje de error Normas estrictas: el método no estático no debe llamarse estáticamente en php

114

Tengo el siguiente archivo php. Sin embargo, cuando veo index.php, aparece el siguiente mensaje de error.

Estándares estrictos: el método no estático Page :: getInstanceByName () no debe llamarse estáticamente en /var/www/webworks/index.php en la línea 12

Espero que alguien pueda decirme cómo solucionar el problema.

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];
    }
espinilla
fuente
15
Hmm, ¿podría ser que estás llamando a un método de forma estática y ese método no está definido como estático? Ya sabes, casi exactamente lo que dice el error, en el número de línea dice ...
Harold1983-

Respuestas:

189

A tus métodos les falta la staticpalabra clave . Cambio

function getInstanceByName($name=''){

a

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

si desea llamarlos estáticamente.

Tenga en cuenta que los métodos estáticos (y Singletons ) son la muerte a la prueba .

También tenga en cuenta que está haciendo demasiado trabajo en el constructor, especialmente todas esas consultas no deberían estar allí. Todo lo que se supone que debe hacer su constructor es establecer el objeto en un estado válido. Si tiene que tener datos de fuera de la clase para hacerlo, considere inyectarlos en lugar de extraerlos. También tenga en cuenta que los constructores no pueden devolver nada. Siempre volverán vacías, por lo que todas estas return falsedeclaraciones no hacen más que terminar la construcción.

Gordon
fuente
2
Los códigos son de este libro ... packtpub.com/cms-design-using-php-and-jquery/book . Creo que deberías escribir un libro, Gordon. :-)
shin
5
@shin Nah, solo repetiría lo que otros han dicho mejor que yo antes. Pero ese es un código realmente malo para un libro que se publicó en diciembre de 2010. ¿Dan alguna razón para omitir alguna palabra clave de visibilidad o no seguir la convención de codificación PEAR? Esperemos que jQuery y la arquitectura general de CMS sean más sólidas.
Gordon
17
@dzona eso estaría ignorando los problemas con el código, no solucionándolo.
Gordon
1
NOTA importante: la publicpalabra clave se usa solo en declaraciones de función / variable dentro de una clase. Ver stackoverflow.com/questions/13341378/…
cssyphus
1
@Gordon, solo curiosidad: ¿por qué aboga por cambiar el método ofensivo a static, en lugar de (re) escribir el código para usar $p = new Page(); $p->getInstanceByName();?
Dennis
21

Creo que esto puede responder a tu pregunta.

Método no estático ... no debe llamarse estáticamente

Si el método no es estático, debe inicializarlo así:

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

O, en PHP 5.4+, puede usar esta sintaxis:

(new ClassName)->method();
Guisante
fuente
Es (nuevo ClassName) -> método (); compatible con PHP 5.3 también?
Jeff
1
@Jeff, usaría (new ClassName())->method();, y creo que es compatible con PHP de 5 a 7
Dennis
1
(new ClassName)->method();no es compatible con PHP 5.3. Solo lo probé.
Sonny
1

Prueba esto:

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

Me funcionó en un caso similar.

Andrés Frías
fuente
1

use className-> function (); en lugar className :: function ();

ulas korpe
fuente
0

return falsegeneralmente está destinado a finalizar la creación del objeto con un error. Es tan simple como eso.

Tomas
fuente
0

Si la resolución de alcance :: tuviera que usarse fuera de la clase, la función o variable respectiva debe declararse como estática

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
fuente
1
¿Puede proporcionar ejemplos para el OP y todos los visitantes futuros?
B001 ᛦ
<? php class Foo {/ * Variable estática * / public static $ static_var = 'variable estática'; / * Función estática * / función estática staticValue () {return 'función estática'; } / * función * / función Valor () {return 'Objeto'; }} echo Foo :: $ variable_estática. "<br/>"; echo Foo :: staticValue (). "<br/>"; $ foo = nuevo Foo (); echo $ foo-> Valor (); / * Espero que este ejemplo te ayude * /
Ravi Krishnan
-1

En lugar de usar la instancia con el operador de resolución de alcance :: porque no se definió como una función estática.

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

cámbielo a:

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

Y funcionará como un encanto.

Lorand
fuente