2010-01-07 52 views
1

在我看來(使用Zend_View的,因此認爲是一個對象),我打電話給對象的屬性和方法來填充像這樣的模板:如何強制在PHP的對象的屬性或方法的方法調用?

<?= $this->user->name ?> // Outputs John Doe 
<br/> 
<?= $this->user->getCompany()->name ?> // Outputs Acme 
<br/> 
<?= $this->method() ?> // Outputs foobar 

如果我讓這個所有財產的請求(如''用戶')通過__get()有什麼辦法可以捕獲後續調用,以便我可以強制對最終輸出值進行方法調用?例如,以便我可以自動轉義輸出。

正如我現在看到的那樣,我要麼在進入數據庫時​​使用輸入,要麼使用像Smarty這樣的編譯模板,或者切換到將每個變量分配給View對象,以便直接控制以強制在輸出數據之前轉義。

+0

我聽說,在ZF 2.0所有返回Zend_View的實例值(使用Zend_View :: __ get()返回)將被自動轉義。 – 2010-01-07 06:35:36

+0

2問題:由於PHP 5.3的要求,2.0還沒有出現,暫時不會有一段時間。它只會自動轉義直接分配給它的值,而不是從對象中獲取的值。 – 2010-01-07 16:21:37

回答

1

您可以使用修飾。看到這個簡單的例子:(?假設這是一個Zend_View的方法)

class ViewObject_Decorator 
{ 
    protected $_decoratedObject; 

    protected $_view; 

    public function __construct($object, Zend_View view) 
    { 
     $this->_decoratedObject = $object; 
     $this->_view = $view; 
    } 

    public function __get($property) 
    { 
     return $this->_view->escape($this->_decoratedObject->$property); 
    } 

    /* 
     maybe implement __call to proxy to decoratedObject methods, etc... 
    */ 
} 

然後您提出__get的方法是這樣的:

public function __get($property) 
{ 
    // decorate the requested object, and send the view along with it. 
    return new ViewObject_Decorator($this->$property, $this); 
} 
0

我開始說第那是因爲你不能(),但經過思考意識到你可以繞過它使返回的值去「到」 __get。就我個人而言,我認爲這將是低效率的,並且還會導致其他問題,例如在沒有轉義的情況下獲得名稱。

要做到這一點,你需要使用__get($ VAR)在每個類,然後逃離之後返回變量。

可能很浪費的,雖然我個人會用

<?= $this->user->escaped_name() ?> 

在類用戶和代表公司

__get($var){ 
    if ($var == 'name') 
    return escape($this->name); 
} 

這只是一個例子,假設$名稱的類是一個非公衆成員。如果在一個數組的索引適合到數組中的元素將被要求如:

return escape($this->data['name']); 

注:我沒有zend_views的知識,但我認爲它不會使任何區別

DC

+0

我不同意,方法'用戶:: escaped_name()'不屬於'用戶',但有東西處理字符串。 – chelmertz 2010-01-07 09:33:16

+0

我同意,我只是試圖堅持用戶的例子。親自如果我不得不使用<?php echo escape($ this-> user-> name); ?> – DeveloperChris 2010-01-07 11:43:46

0

手動方式是直接使用轉義()視圖助手在模板這樣的:

<?= $this->escape($this->user->name) ?> // Outputs John Doe 
<br/> 
<?= $this->escape($this->user->getCompany()->name) ?> // Outputs Acme 
<br/> 
<?= $this->escape($this->method()) ?> // Outputs foobar 

到自動執行它的最簡單的方法是使用一個流封包。 Zend Framework提供了Zend_View_Stream,用於自動將短標籤轉換爲長標籤。

$view->setUseStreamWrapper(true); 

你需要把它擴大到自動跳脫任何使用<?=:這是使用啓用。在包裝中使用的代碼是這樣的:

$find = '/<?=[ ]*([^;>]*?|[^;?]*?)[; ]*?>/'; 
$replace = "<?php echo $this->escape($1); ?>"; 
$this->data = preg_replace($find, $replace, $this->data); 

很明顯,使用流包裝也有一些性能影響。

的進一步的細節在這裏:

+0

我想你錯過了關於自動轉義輸出的部分。 :P – 2010-01-07 14:38:19

+0

你是對的:) – 2010-01-08 07:10:42

0

你可以擴展視圖對象,然後重寫__get()方法來逃避所有輸出按需要。

您可以使用:

$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); 
$viewRenderer->setView(new My_View()); 

視圖對象更改爲您創建一個。

+0

這就是我想要做的。我問的是,如果有一種方法可以強制調用escape()名稱,該名稱是Zend_View包含的對象的屬性調用。 – 2010-01-07 16:20:18

0

使用PHPTAL作爲您的view

默認情況下,它將所有內容都轉義(將模板編譯爲PHP,其中所有必需的調用都會自動添加htmlspecialchars())。

${this/user/getCompany/name} <!-- it's safe! --> 
相關問題