move_uploaded_file()期望参数2是有效路径,给定对象

时间:2016-04-08 16:55:32

标签: php symfony

我正在使用Symfony 2.3来保存由表单POST上传的文件。

这是我在控制器中使用的代码:

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

在水下,Symfony执行此代码来移动文件:

"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)" 

公共目录有777个权限。

这是我得到的错误:

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

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

if (!@move_uploaded_file($this->getPathname(), $target)) {

// etc...

我正在使用PHP 5.3。

更新

这是执行move_uploaded_file()的代码剪切:

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);
}

$ target“变量在这里创建:

/**
 * 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 () {}

$ target变量就是File类。它有一个__toString()方法,继承自SplFileInfo:

{{1}}

但不知怎的,__toString方法无效。

1 个答案:

答案 0 :(得分:3)

  

但不知何故__toString方法无法正常工作

它是“魔术方法”之一,当在字符串上下文中使用对象时会自动调用它 - 例如,如果你有'foo' . $object

但我不认为假设在这种情况下工作。因为PHP是松散类型的,所以你可以将任何传递给move_uploaded_file。此时不会自动转换为字符串。然后在内部,该函数仅检查参数是否为字符串,但不尝试将其转换为一个 - 因为这没有意义,它可能是任何类型的对象,并且无法判断调用__toString是否会产生有效的文件路径。

您现在可能想知道,为什么在错误消息中我们会看到路径:

  

无法将文件“/ tmp / phpBM9kw8”移动到“/home2/divine/Symfony/src/App/Bundle/Resources/public/files/book.pdf”

我的猜测是,当组装该错误消息时,会进行字符串连接,以便在此特定点调用__toString。

如果您愿意修改Symfony源代码,我认为这应该是一个简单的解决方案,如果您只是更改此行

if (!@move_uploaded_file($this->getPathname(), $target)) {

if (!@move_uploaded_file($this->getPathname(), ''.$target)) {

- 然后再次出现这种情况,其中将调用__toString,因为该对象通过将其与字符串(空字符串)连接而转移到字符串上下文中,因为我们不想篡改结果值。 )

当然,直接修改框架文件并不是处理此问题的最佳方法 - 在下次更新后,我们的更改可能会再次丢失。我建议您检查Symfony bugtracker(他们应该有类似的东西),看看这是否已经存在已知问题,是否存在官方补丁文件;并以其他方式将其报告为错误,以便可以在将来的版本中修复它。