2016-04-08 136 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

相关问题