2016-04-08 137 views
1

我使用Symfony 2.3來保存表單POST上傳的文件。move_uploaded_file()期望參數2是有效的路徑,給定的對象

這是我在控制器中使用的代碼:

$fileDir = '/home2/divine/Symfony/src/App/Bundle/Resources/public/files'; 

$form['my_file']->getData()->move($fileDir, 'book.pdf'); 

在水,Symfony的執行這段代碼移動文件:

move_uploaded_file("/tmp/phpBM9kw8", "/home2/divine/Symfony/src/App/Bundle/Resources/public/files/book.pdf"); 

公共目錄中有777個權限。

這是我的錯誤:

"Could not move the file "/tmp/phpBM9kw8" to "/home2/divine/Symfony/src/App/Bundle/Resources/public/files/book.pdf" 

(move_uploaded_file() expects parameter 2 to be valid path, object given)" 

我使用PHP 5.3。

更新:

這是執行move_uploaded_file()以剪斷代碼:

// Class: Symfony\Component\HttpFoundation\File\UploadedFile 

$target = $this->getTargetFile($directory, $name); 

if ([email protected]_uploaded_file($this->getPathname(), $target)) { 

// etc... 

的$目標」變量在這裏創建:

protected function getTargetFile($directory, $name = null) { 

// Some error handling here... 

    $target = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : $this->getName($name)); 

    return new File($target, false); 
} 

的$目標變量是一個File類,它有一個繼承自SplFileInfo的__toString()方法:

/** 
* Returns the path to the file as a string 
* @link http://php.net/manual/en/splfileinfo.tostring.php 
* @return string the path to the file. 
* @since 5.1.2 
*/ 
public function __toString() {} 

但不知何故__toString方法不起作用。

+0

如您所見,其中一個參數是一個對象,而不是一個字符串或不能轉換爲字符串(即該對象沒有__toString()方法)。順便說一句,我確實希望它只是你的開發機器。 777對於現場環境來說是個壞主意...... –

+0

是的,錯誤確實表明第二個參數不是字符串。但我爲此感到困惑。這對我來說絕對是一個字符串。 – BigJ

+0

'public/files /';'需要尾部斜線。因爲它被讀作'public/filesbook.pdf';'沒有它,而不是'public/files/book.pdf';' –

回答

3

但不知何故,該__toString方法是行不通的

它的「魔術方法」之一,當物體在字符串上下文中使用它會導致自動調用 - 如果你有這樣的例子'foo' . $object

但我不認爲這是假設在這裏工作的情況。由於PHP是鬆散類型的,您可以將任何東西傳遞到move_uploaded_file。此時不會自動轉換爲字符串。然後在內部,函數只檢查參數是否是字符串,但不會嘗試將其轉換爲一個字符串 - 因爲這沒什麼意義,它可能是任何類型的對象,並且沒有辦法告訴如果調用__toString會導致有效的文件路徑。


現在你可能會問,爲什麼在錯誤信息,我們也能看到的路徑:

無法移動的文件 「/ tmp目錄/ phpBM9kw8」 到「/ HOME2 /神聖/ Symfony的/src/App/Bundle/Resources/public/files/book.pdf」

我的猜測是,當組裝該錯誤消息,有字符串連接回事,讓__toString不會被調用這具體點。


如果你願意修改Symfony的源代碼,我覺得這應該是一個容易解決的工作,如果你只是改變這一行

if ([email protected]_uploaded_file($this->getPathname(), $target)) { 

if ([email protected]_uploaded_file($this->getPathname(), ''.$target)) { 

- 那麼你再次遇到了__ toString被調用的情況,因爲通過將對象與一個字符串(一個空字符串)連接起來,將對象轉移到字符串上下文中,因爲我們不想篡改結果。值)


當然直接修改的框架的文件中沒有處理這個問題最值得推薦的方式 - 在下次更新後,我們的變化可能會再次失去。我建議你檢查Symfony bugtracker(他們應該有類似的東西),看看這是否已知問題,以及是否存在官方的補丁文件;否則將其報告爲錯誤,以便在將來的版本中修復它。

+0

Thnx!事實上,__toString()方法不會自動調用,concat技巧確實有效。奇怪的是,這個代碼在過去有效。我會檢查錯誤跟蹤器。 – BigJ

相關問題