programing

PHP에서 static 메서드와 nonstatic 메서드를 선언할 수 있습니까?

copysource 2022. 9. 25. 14:50
반응형

PHP에서 static 메서드와 nonstatic 메서드를 선언할 수 있습니까?

오브젝트 내의 메서드를 스태틱메서드와 비 스태틱메서드로 호출하는 이름이 같은 것으로 선언할 수 있습니까?

static 메서드 "send"와 static 함수를 호출하는 non-static 메서드를 가진 클래스를 만들고 싶습니다.예를 들어 다음과 같습니다.

class test {
    private $text;
    public static function instance() {
        return new test();
    }

    public function setText($text) {
        $this->text = $text;
        return $this;
    }

    public function send() {
        self::send($this->text);
    }

    public static function send($text) {
        // send something
    }
}

이 두 가지 함수를 호출할 수 있으면 좋겠습니다.

test::send("Hello World!");

그리고.

test::instance()->setText("Hello World")->send();

가능합니까?

수 있는데 좀 까다롭네요.오버로드로 해야 합니다.및 마법의 메서드입니다.

class test {
    private $text;
    public static function instance() {
        return new test();
    }

    public function setText($text) {
        $this->text = $text;
        return $this;
    }

    public function sendObject() {
        self::send($this->text);
    }

    public static function sendText($text) {
        // send something
    }

    public function __call($name, $arguments) {
        if ($name === 'send') {
            call_user_func(array($this, 'sendObject'));
        }
    }

    public static function __callStatic($name, $arguments) {
        if ($name === 'send') {
            call_user_func(array('test', 'sendText'), $arguments[0]);
        }
    }
}

PHP > = 5.3이 있으면 코드를 따르기 어렵기 때문에 이상적인 솔루션은 아닙니다.

숨겨진 클래스를 생성자로 만들고 숨겨진 클래스 메서드와 동일한 정적 메서드를 가진 부모 클래스 내의 숨겨진 클래스를 반환합니다.

// Parent class

class Hook {

    protected static $hooks = [];

    public function __construct() {
        return new __Hook();
    }

    public static function on($event, $fn) {
        self::$hooks[$event][] = $fn;
    }

}


// Hidden class

class __Hook {

    protected $hooks = [];

    public function on($event, $fn) {
        $this->hooks[$event][] = $fn;
    }

}

정적으로 호출하려면:

Hook::on("click", function() {});

동적으로 호출하려면:

$hook = new Hook;
$hook->on("click", function() {});

아니요, 같은 이름의 두 가지 방법을 사용할 수 없습니다.기본적으로 동일한 작업을 수행할 수 있는 방법은 몇 가지 메서드의 이름을 변경하는 것입니다. " " " " "test::send("Hello World!");로로 합니다.test::sendMessage("Hello World!"); 됩니다.이 인수는 메서드의 합니다.메서드의 기능을 변경하는 옵션의 text 인수를 사용하여 단일 전송 메서드를 만듭니다.

public function send($text = false) {
    if (!$text) {
        $text = $this -> text;
    }

    // Send something
}

나는 당신이 왜 정전기능을 필요로 하는지 잘 알고 있다.

나는 이것이 무슨 일이 있어도 피해야 한다는 것에 동의하지만 도움이 될 수 있는 경우도 있다.

대부분의 경우 코드를 읽을 수 없거나 관리할 수 없게 됩니다.

날 믿어, 나도 그런 길을 걸어왔어.

이 예는 여전히 실용적일 수 있는 사용 사례 시나리오의 예입니다.

나는 케이크를 연장한다.기본 파일 처리 클래스로 PHP 3.0의 파일 클래스입니다.

정적 MIME 타입의 추측기를 삽입하고 싶었다.

경우에 따라서는 실제 파일이 아닌 파일 이름을 사용할 수 있으며, 이 경우 몇 가지 가정을 해야 합니다.(파일이 존재하는 경우 파일 이름에서 MIME을 가져오거나 제공된 파일 이름 확장자를 사용하십시오.

오브젝트를 실제로 인스턴스화한 경우 기본 mime() 메서드가 동작하지만 실패할 경우 오브젝트에서 파일 이름을 추출하고 대신 정적 메서드를 호출해야 합니다.

혼동을 피하기 위해 같은 메서드를 호출하여 mime 타입을 취득하는 것이 목적:

정적:

NS\File::type('path/to/file.txt')

오브젝트로서

$f = new NS\File('path/to/file.txt');
$f->type();

확장 클래스의 예를 다음에 나타냅니다.

<?php

namespace NS;

class File extends \Cake\Utility\File
{

    public function __call($method, $args) {
        return call_user_func_array([get_called_class(), 'obj'.ucfirst($method)], $args);
    }
    public static function __callStatic($method, $args) {
        return call_user_func_array([get_called_class(), 'static'.ucfirst($method)], $args);
    }

    public function objType($filename=null){
        $mime = false;
        if(!$filename){
            $mime = $this->mime();
            $filename = $this->path;
        }
        if(!$mime){
            $mime = static::getMime($filename);
        }
        return $mime;
    }

    public static function staticType($filename=null){
        return static::getMime($filename);
    }

    public static function getMime($filename = null)
    {
        $mimes = [
            'txt' => 'text/plain',
            'htm' => 'text/html',
            'html' => 'text/html',
            'php' => 'text/html',
            'ctp' => 'text/html',
            'twig' => 'text/html',
            'css' => 'text/css',
            'js' => 'application/javascript',
            'json' => 'application/json',
            'xml' => 'application/xml',
            'swf' => 'application/x-shockwave-flash',
            'flv' => 'video/x-flv',
            // images
            'png' => 'image/png',
            'jpe' => 'image/jpeg',
            'jpeg' => 'image/jpeg',
            'jpg' => 'image/jpeg',
            'gif' => 'image/gif',
            'bmp' => 'image/bmp',
            'ico' => 'image/vnd.microsoft.icon',
            'tiff' => 'image/tiff',
            'tif' => 'image/tiff',
            'svg' => 'image/svg+xml',
            'svgz' => 'image/svg+xml',
            // archives
            'zip' => 'application/zip',
            'rar' => 'application/x-rar-compressed',
            'exe' => 'application/x-msdownload',
            'msi' => 'application/x-msdownload',
            'cab' => 'application/vnd.ms-cab-compressed',
            // audio/video
            'mp3' => 'audio/mpeg',
            'qt' => 'video/quicktime',
            'mov' => 'video/quicktime',
            // adobe
            'pdf' => 'application/pdf',
            'psd' => 'image/vnd.adobe.photoshop',
            'ai' => 'application/postscript',
            'eps' => 'application/postscript',
            'ps' => 'application/postscript',
            // ms office
            'doc' => 'application/msword',
            'rtf' => 'application/rtf',
            'xls' => 'application/vnd.ms-excel',
            'ppt' => 'application/vnd.ms-powerpoint',
            // open office
            'odt' => 'application/vnd.oasis.opendocument.text',
            'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
        ];
        $e = explode('.', $filename);
        $ext = strtolower(array_pop($e));
        if (array_key_exists($ext, $mimes)) {
            $mime = $mimes[$ext];
        } elseif (function_exists('finfo_open') && is_file($filename)) {
            $finfo = finfo_open(FILEINFO_MIME);
            $mime = finfo_file($finfo, $filename);
            finfo_close($finfo);
        } else {
            $mime = 'application/octet-stream';
        }
        return $mime;
    }
}

php에서는 메서드 가시성(Public, Private, Protected)을 가진 클래스 메서드를 설정/할당할 수 있습니다.클래스 속성은 클래스 밖에서 액세스할 수 있는지 여부와 같이 클래스 메서드 또는 클래스 속성의 restric 배포를 선언할 수 있습니다.

전화를 걸기 위해 두 가지 접근법이 있는데

  1. 정적(셀프::)
  2. 비정적($this->)

몇 가지 메서드와 속성이 있는 수업을 듣자.가시광선 및 호출 접근 방식을 가지고 있습니다.

    <?php

    class Foo {

     public const WELCOME ='This is WELCOME Non Static Constant For Foo Class';
    public string $text='This is A Text Non Static Foo Class Properties';
    public static string $texter='This is A Texter Foo Static Class Properties';
    private string $ptext='This is a private string Non Static properties of Class Foo';
      
    
    public static function Bar()
    {
        echo "Static Method Bar is calling\n";
    }
    
    public function Baz()
    {
        echo "Non Static Method Baz is calling \n";
    }
    
    
    protected function Another()
    {
        echo "Non Static Method Another is calling \n";
    }
    
    private function Again()
    {
        echo "Non Static Private Method Again is calling \n";
    }
    
    protected static function AnotherOne()
    {
        echo "Non Static Method Another is calling \n";
    }
    
    private static function AgainOne()
    {
        echo "Non Static Private Method Again is calling \n";
    }
    
    
    public static function bypass()
    {
        return self::AgainOne();
    }
    
    public function getPText()
    {
        return $this->ptext;
    }
    
    
    
}
?>

이 클래스를 테스트합니다.

<?php

//Non Static Call By Creating an $app instance of Foo Class..
$app = new Foo();
 echo $app->WELCOME;        // Undefined property: Foo::$WELCOME
 echo $app->text;           // This is A Text Non Static Foo Class Properties
 echo $app->texter;         // Accessing static property Foo::$texter as non static
 echo $app->Bar();          // Static Method Bar is calling
 echo $app->Baz();          // Non Static Method Baz is calling 
 echo $app->Another();      // Uncaught Error: Call to protected method Foo::Another() from global scope
 echo $app->Again();        // Uncaught Error: Call to private method Foo::Again() from global scope
 echo $app->AnotherOne();   // Uncaught Error: Call to protected method Foo::AnotherOne() from global scope
 echo $app->AgainOne();     // Uncaught Error: Call to private method Foo::AgainOne() from global scope
 echo $app->bypass();       // Non Static Private Method Again is calling 
 echo $app->ptext;          // Uncaught Error: Cannot access private property Foo::$ptext
 echo $app->getPText();     // This is a private string Non Static properties of Class Foo 

//Static Call
 echo Foo::WELCOME;         // This is WELCOME Non Static Constant For Foo Class
 echo Foo::text;            // Uncaught Error: Undefined constant Foo::text
 echo Foo::texter;          // Uncaught Error: Undefined constant Foo::texter
 echo Foo::Bar();           // Static Method Bar is calling
 echo Foo::Baz();           // Uncaught Error: Non-static method Foo::Baz() cannot be called statically
 echo Foo::Another();       // Uncaught Error: Call to protected method Foo::Another() from global scope
 echo Foo::Again();         // Uncaught Error: Call to private method Foo::Again() from global scope 
 echo Foo::AnotherOne();    // Uncaught Error: Call to protected method Foo::AnotherOne() from global scope
 echo Foo::AgainOne();      // Uncaught Error: Call to private method Foo::AgainOne() from global scope
 echo Foo::bypass();        // Non Static Private Method Again is calling 
 
 ?>

여기서 In Action을 참조하십시오.

오래된 스레드를 범핑해서 죄송합니다만, @lonesday의 답변에 대해 자세히 설명하겠습니다.(첫 번째 코드 샘플에 대해 @lonesday 감사합니다.)

저도 이것을 실험하고 있었습니다만, 당초의 투고에서는 메서드라고 불렀기 때문에 메서드를 부르고 싶지 않았습니다.대신 다음과 같은 기능이 있습니다.

    class Emailer {

    private $recipient;

    public function to( $recipient )
    {
        $this->recipient = $recipient;
        return $this;
    }

    public function sendNonStatic()
    {
        self::mailer( $this->recipient );
    }

    public static function sendStatic( $recipient )
    {
        self::mailer( $recipient );
    }

    public function __call( $name, $arguments )
    {
        if ( $name === 'send' ) {
            call_user_func( array( $this, 'sendNonStatic' ) );
        }
    }

    public static function mailer( $recipient )
    {
        // send()
        echo $recipient . '<br>';
    }

    public static function __callStatic( $name, $arguments )
    {
        if ( $name === 'send' ) {
            call_user_func( array( 'Emailer', 'sendStatic' ), $arguments[0] );
        }
    }
}

Emailer::send( 'foo@foo.foo' );

$Emailer = new Emailer;
$Emailer->to( 'bar@bar.bar' );
$Emailer->send();

언급URL : https://stackoverflow.com/questions/11331616/is-it-possible-to-declare-a-method-static-and-nonstatic-in-php

반응형