2012-02-21 63 views
7

我有一個字符串包含類名,我希望得到一個常量,並從該類調用(靜態)方法。從字符串訪問類常量和靜態方法

<?php 
$myclass = 'b'; // My class I wish to use 

$x = new x($myclass); // Create an instance of x 
$response = $x->runMethod(); // Call "runMethod" which calls my desired method 

// This is my class I use to access the other classes 
class x { 
    private $myclass = NULL; 

    public function __construct ($myclass) { 
     if(is_string($myclass)) { 
      // Assuming the input has a valid class name 
      $this->myclass = $myclass; 
     } 
    } 

    public function runMethod() { 
     // Get the selected constant here 
     print $this->myclass::CONSTANT; 

     // Call the selected method here 
     return $this->myclass::method('input string'); 
    } 
} 


// These are my class(es) I want to access 
abstract class a { 
    const CONSTANT = 'this is my constant'; 

    public static function method ($str) { 
     return $str; 
    } 
} 

class b extends a { 
    const CONSTANT = 'this is my new constant'; 

    public static function method ($str) { 
     return 'this is my method, and this is my string: '. $str; 
    } 
} 
?> 

如我所料(或多或少),使用$variable::CONSTANT$variable::method();不起作用。

在問我嘗試過什麼之前;我已經嘗試了很多我基本忘記的東西。

這樣做的最佳方法是什麼?提前致謝。

回答

22

要訪問不變,使用constant()

constant($this->myClass.'::CONSTANT'); 

被告知:如果您在使用命名空間,您需要將您的命名空間專門添加到字符串,即使從同一個命名空間調用constant()

對於呼叫,你將不得不使用call_user_func()

call_user_func(array($this->myclass, 'method')); 

但是:這一切不是很有效,所以你可能希望再看看你的對象層次結構的設計。可能有更好的方法來達到預期的結果,使用繼承等。

+0

並且怎麼樣的方法? – 2012-02-21 15:53:42

+0

更新了答案! Powe! – Rijk 2012-02-21 15:58:47

+0

Pow!快速和簡單的答案,就像一個魅力。謝謝! – 2012-02-21 16:07:23

1

您可以通過設置一個臨時變量來實現它。不是最優雅的方式,但它的工作原理。

public function runMethod() { 
    // Temporary variable 
    $myclass = $this->myclass; 
    // Get the selected constant here 
    print $myclass::CONSTANT; 

    // Call the selected method here 
    return $myclass::method('input string'); 
} 

我想這是與::的模糊性做,至少那個什麼錯誤消息在(PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM

+1

我只是想寫出完全相同的答案。這將是最「理性」的版本,我想。儘管用繼承進行完整的重寫會好很多。 – apfelbox 2012-02-21 16:04:30

2

使用call_user_func暗示調用靜態方法:

call_user_func(array($className, $methodName), $parameter); 
1

定義爲抽象的類可能不會被實例化,並且任何包含至少一個抽象方法的類也必須是抽象的。定義爲抽象的方法只是聲明方法的簽名 - 他們不能定義實現。

當從一個抽象類繼承時,在父類的聲明中標記爲抽象的所有方法必須由子定義;另外,這些方法必須用相同(或更少限制)的可見性來定義。例如,如果抽象方法被定義爲受保護的,則必須將函數實現定義爲protected或public,但不是私有的。此外,方法的簽名必須匹配,即類型提示和所需參數的數量必須相同。這也適用於PHP 5.4以上的構造函數。在5.4構造函數簽名之前可能會有所不同。 參考http://php.net/manual/en/language.oop5.abstract.php

0

在PHP 7,你可以使用此代碼

echo 'my class name'::$b; 
+1

雖然此答案可能解決OP的問題,但建議您提供一個清楚的解釋,說明如何實現解決方案。只需發佈僅有代碼的答案可能對OP和未來的用戶無益。請詳細說明。 – 2017-05-21 08:57:41

+1

解決方案很明確!因爲問題的標題是**訪問類常量和字符串的靜態方法** – 2017-05-21 09:29:40