PHP.mk документација

Анонимни класи

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

language.oop5.anonymous.php PHP.net прокси Преводот е вчитан
Оригинал на PHP.net
Патека language.oop5.anonymous.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + преведен приказ Кодовите, табелите и белешките остануваат читливи во истиот тек.
Анонимни класи

Референца за `language.oop5.anonymous.php` со подобрена типографија и навигација.

language.oop5.anonymous.php

Анонимни класи

Анонимните класи се корисни кога треба да се создадат едноставни, еднократни објекти.

<?php

// Using an explicit class
class Logger
{
public function
log($msg)
{
echo
$msg;
}
}

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

// Using an anonymous class
$util->setLogger(new class {
public function
log($msg)
{
echo
$msg;
}
});

Тие можат да поминуваат аргументи низ нивните конструктори, да наследуваат други класи, да имплементираат интерфејси и да користат трајти исто како што може нормална класа:

<?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;
});

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

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

Вгнездувањето на анонимна класа во друга класа не ѝ дава пристап до никакви приватни или заштитени методи или својства на таа надворешна класа. За да се користат заштитените својства или методи на надворешната класа, анонимната класа може да ја наследи надворешната класа. За да се користат приватните својства на надворешната класа во анонимната класа, тие мора да се поминат низ нејзиниот конструктор:

<?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();

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

6

Сите објекти создадени од иста декларација на анонимна класа се инстанци на таа класа.

<?php
function anonymous_class()
{
return new class {};
}

if (
get_class(anonymous_class()) === get_class(anonymous_class())) {
echo
'same class';
} else {
echo
'different class';
}

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

same class

Забелешка:

Имајте предвид дека на анонимните класи им се доделува име од страна на моторот, како што е прикажано во следниот пример. Ова име мора да се смета за имплементациски детал, на кој не треба да се потпирате.

<?php
echo get_class(new class {});

Горниот пример ќе прикаже нешто слично на:

class@anonymous/in/oNi1A0x7f8636ad2021

Анонимни класи само за читање

Од PHP 8.3.0, readonly модификаторот може да се примени на анонимни класи.

Пример #1 Дефинирање на анонимна класа само за читање

<?php
// Using an anonymous class
var_dump(new readonly class('[DEBUG]') {
public function
__construct(private string $prefix)
{
}

public function
log($msg)
{
echo
$this->prefix . ' ' . $msg;
}
});

Белешки од корисници 8 белешки

Анонимен
пред 10 години
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";
ytubeshareit на gmail точка com
пред 8 години
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;
?>
sebastian.wasser на gmail
пред 7 години
I wanted to share my findings on static properties of anonymous classes.

So, given an anonymous class' object generating function like this:

<?php
function nc () {
    return new class {
        public static $prop = [];
    };
}
?>

Getting a new object and changing the static property:

<?php
$a = nc();
$a::$prop[] = 'a';

var_dump($a::$prop);
// array(1) {
//   [0] =>
//   string(1) "a"
// }
?>

Now getting another object and changing the static property will change the original one, meaning that the static property is truly static:

<?php
$b = nc();
$b::$prop[] = 'b';

var_dump($b::$prop); // Same as var_dump($a::$prop);
// array(2) {
//   [0] =>
//   string(1) "a"
//   [1] =>
//   string(1) "b"
// }

assert($a::$prop === $b::$prop); // true
?>
ј.м \ џејмсвеб \ ка
пред 8 години
/* I like the idea of OneShot classes.
Thanks to that Anonymous bro\sist for precising   
new class( $a, $b )
¯¯¯¯¯¯¯¯¯

If you are looking for "Delayed OneShot Anonymous Classes" for any reason (like the reason: loading files in a readable manner while not using autoload), it would probably look something like this; */

$u = function()use(&$u){
    $u = new class{private $name = 'Utils';};
};

$w = function(&$rewrite)use(&$w){
    $w = null;
    $rewrite = new class{private $name = 'DataUtils';};
};

// Usage;
var_dump(
    array(
        'Delayed',
        '( Self Destructive )',
        'Anonymous Class Creation',
        array(
            'Before ( $u )' => $u,
            'Running ( $u() )' => $u(),
            'After ( $u )' => $u,
        ),
        0,0,
        0,0,
        0,0,
        'Delayed',
        '( Overwriting && Self Destructive )',
        'Anonymous Class Creation',
        array(
            'Before ( $w )' => $w,
            'Running ( $w($u) )' => $w($u),
            'After ( $w )' => $w,
            'After ( $u )' => $u
        )
    )
);

// btw : oh shoot I failed a spam challenge
joey
пред 6 години
The only way to type hint this would appear to be as object.

If you need multiple instances of an anonymous class in a function you can use:

$class = function(string $arg):object {
    return new class($arg) {
        public function __construct(string $arg) {
            $this->ow = $arg;
        }
    };
};

Though for the sake of structure it's ill advised to do something like this outside of a single scope or that's used across multiple files. If you class is only used in one scope however then it's probably not a code mess problem.
razvan_bc на yahoo точка com
пред 6 години
you can try these

<?php 

$oracle=&$_['nice_php'];
$_['nice_php']=(function(){
    return new class{
        public static function say($msg){
            echo $msg;
        }

        public static function sp(){
            echo self::say(' ');
        }

    };
});

/*
$_['nice_php']()::say('Hello');
$_['nice_php']()::sp();
$_['nice_php']()::say('World');
$_['nice_php']()::sp();
$_['nice_php']()::say('!');
//almost the same code bottom
*/

$oracle()::say('Hello');
$oracle()::sp();
$oracle()::say('World');
$oracle()::sp();
$oracle()::say('!');
?>
ismaelj+php на hotmail точка com
пред 1 година
Thanks to the new property hooks in PHP 8.4 (https://wiki.php.net/rfc/property-hooks) and anonymous functions, now we can create an inner class instantiated only on use:

<?php
class BaseClass {
  public function __construct() { echo "base class\n"; }

  public $childClass  { set {}  get {
    if ($this->childClass === null ) {
      $this->childClass = new class {
        public function __construct() { echo "  child class\n"; }
        public function say(string $s) : void { echo "     $s\n"; }
      };
    }

    return $this->childClass;
    }
  }
}

$base = new BaseClass();

$base->childClass->say('Hello');
$base->childClass->say('World');

/*
Output:

base class
  child class
     Hello
     World
*/
?>

The obvious downside is that you can't set a type to the child class, unless  you define an interface and the child class implements it or if the child class extends an existing class:

<?php
class ParentClass {
  public function say(string $s) : void { echo "     $s\n"; }
}

class BaseClass {
  public function __construct() { echo "base class\n"; }

  public ParentClass $childClass { set {}  get {
    if (!isset($this->childClass)) {
      $this->childClass = new class extends ParentClass {
        public function __construct() { echo "  child class\n"; }
      };
    }

    return $this->childClass;
    }
  }
}

$base = new BaseClass();

$base->childClass->say('Hello');
$base->childClass->say('World');

/*
Output:

base class
  child class
     Hello
     World
*/
?>
?>

This can be also done with functions, but  with hooks to me looks more like in other languages that have this functionality natively.
piotr на maslosoft точка com
пред 8 години
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).
На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.