PHP 7.2.0 Beta 3 Released

Classes anonymes

Le support pour les classes anonymes a été rajouté en PHP 7. Les classes anonymes sont utiles lorsque de simples objets uniques ont besoin d'être créés.

<?php

// Avant PHP 7 
class Logger
{
    public function 
log($msg)
    {
        echo 
$msg;
    }
}

$util->setLogger(new Logger());

// PHP 7+ code
$util->setLogger(new class {
    public function 
log($msg)
    {
        echo 
$msg;
    }
});

On peut leur passer des arguments via le constructeur, elles peuvent étendre d'autres classes, implémenter des interfaces ou utiliser des traits comme avec une classe normale.

<?php

class SomeClass {}
interface 
SomeInterface {}
trait 
SomeTrait {}

var_dump(new class(10) extends SomeClass implements SomeInterface {
    private 
$num;

    public function 
__construct($num)
    {
        
$this->num $num;
    }

    use 
SomeTrait;
});

L'exemple ci-dessus va afficher :

object(class@anonymous)#1 (1) {
  ["Command line code0x104c5b612":"class@anonymous":private]=>
  int(10)
}

Imbriquer une classe anonyme à l'intérieur d'une autre classe ne donne pas accès aux méthodes ou propriétés privées ou protégées de la classe contenante. Afin d'utiliser des méthodes ou propriétés protégées de la classe contenante, la classe anonyme doit étendre celle ci. Pour utiliser les propriétés privées ou protégées de la classe contenant dans la classe anonyme, celles ci doivent être passées via le constructeur.

<?php

class Outer
{
    private 
$prop 1;
    protected 
$prop2 2;

    protected function 
func1()
    {
        return 
3;
    }

    public function 
func2()
    {
        return new class(
$this->prop) extends Outer {
            private 
$prop3;

            public function 
__construct($prop)
            {
                
$this->prop3 $prop;
            }

            public function 
func3()
            {
                return 
$this->prop2 $this->prop3 $this->func1();
            }
        };
    }
}

echo (new 
Outer)->func2()->func3();

L'exemple ci-dessus va afficher :

6
add a note add a note

User Contributed Notes 4 notes

up
13
Anonymous
1 year ago
Below three examples describe anonymous class with very simple and basic but quite understandable example

<?php
// First way - anonymous class assigned directly to variable
$ano_class_obj = new class{
    public
$prop1 = 'hello';
    public
$prop2 = 754;
    const
SETT = 'some config';

    public function
getValue()
    {
       
// do some operation
       
return 'some returned value';
    }

    public function
getValueWithArgu($str)
    {
       
// do some operation
       
return 'returned value is '.$str;
    }
};

echo
"\n";

var_dump($ano_class_obj);
echo
"\n";

echo
$ano_class_obj->prop1;
echo
"\n";

echo
$ano_class_obj->prop2;
echo
"\n";

echo
$ano_class_obj::SETT;
echo
"\n";

echo
$ano_class_obj->getValue();
echo
"\n";

echo
$ano_class_obj->getValueWithArgu('OOP');
echo
"\n";

echo
"\n";

// Second way - anonymous class assigned to variable via defined function
$ano_class_obj_with_func = ano_func();

function
ano_func()
{
    return new class {
        public
$prop1 = 'hello';
        public
$prop2 = 754;
        const
SETT = 'some config';

        public function
getValue()
        {
           
// do some operation
           
return 'some returned value';
        }

        public function
getValueWithArgu($str)
        {
           
// do some operation
           
return 'returned value is '.$str;
        }
    };
}

echo
"\n";

var_dump($ano_class_obj_with_func);
echo
"\n";

echo
$ano_class_obj_with_func->prop1;
echo
"\n";

echo
$ano_class_obj_with_func->prop2;
echo
"\n";

echo
$ano_class_obj_with_func::SETT;
echo
"\n";

echo
$ano_class_obj_with_func->getValue();
echo
"\n";

echo
$ano_class_obj_with_func->getValueWithArgu('OOP');
echo
"\n";

echo
"\n";

// Third way - passing argument to anonymous class via constructors
$arg = 1; // we got it by some operation
$config = [2, false]; // we got it by some operation
$ano_class_obj_with_arg = ano_func_with_arg($arg, $config);

function
ano_func_with_arg($arg, $config)
{
    return new class(
$arg, $config) {
        public
$prop1 = 'hello';
        public
$prop2 = 754;
        public
$prop3, $config;
        const
SETT = 'some config';

        public function
__construct($arg, $config)
        {
           
$this->prop3 = $arg;
           
$this->config =$config;
        }

        public function
getValue()
        {
           
// do some operation
           
return 'some returned value';
        }

        public function
getValueWithArgu($str)
        {
           
// do some operation
           
return 'returned value is '.$str;
        }
    };
}

echo
"\n";

var_dump($ano_class_obj_with_arg);
echo
"\n";

echo
$ano_class_obj_with_arg->prop1;
echo
"\n";

echo
$ano_class_obj_with_arg->prop2;
echo
"\n";

echo
$ano_class_obj_with_arg::SETT;
echo
"\n";

echo
$ano_class_obj_with_arg->getValue();
echo
"\n";

echo
$ano_class_obj_with_arg->getValueWithArgu('OOP');
echo
"\n";

echo
"\n";
up
0
ytubeshareit at gmail dot com
3 months ago
Anonymous classes are syntax sugar that may appear deceiving to some.
The 'anonymous' class is still parsed into the global scope, where it is auto assigned a name, and every time the class is needed, that global class definition is used.  Example to illustrate....

The anonymous class version...
<?php

function return_anon(){
    return new class{
         public static
$str="foo"
    };
}
$test=return_anon();
echo
$test::$str; //ouputs foo

//we can still access the 'anon' class directly in the global scope!
$another=get_class($test); //get the auto assigned name
echo $another::$str;    //outputs foo
?>

The above is functionally the same as doing this....
<?php
class I_named_this_one{
    public static
$str="foo";
}
function
return_not_anon(){
    return
'I_named_this_one';
}
$clzz=return_not_anon();//get class name
echo $clzz::$str;
?>
up
-1
piotr at maslosoft dot com
3 months ago
Please note that class name returned by `get_class` might contain null bytes, as is the case in my version of PHP (7.1.4).

Name will change when class starting line or it's body is changed.

Yes, name is implementation detail that should not be relied upon, but in some rare use cases it is required (annotating anonymous class).
up
-8
primipilus13 at gmail dot com
10 months ago
<?php

// using constructor and extends in anonymous class 

class A
{
    private
$name;   

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

    public function
getName()
    {
        return
$this->name;
    }
}

$b = new class('anonymous') extends A
{
    public function
getName()
    {
        return
parent::getName() . ' class';
    }
};

echo
$b->getName(), PHP_EOL;

// result: anonimous class
To Top