【问题标题】:SplTempFileObject and ImagickSplTempFileObject 和 imagick
【发布时间】:2012-09-23 18:39:16
【问题描述】:

我正在使用 MySQL 数据库来保存一些字体。我需要使用自定义字体系列文本创建图像。我正在使用 SplTempFileObject 来处理 setFont 方法,但这是 imagick 所说的:

Fatal error: Uncaught exception 'ImagickDrawException' with message 'The given font is not found in the ImageMagick configuration and the file ($_SERVER['DOCUMENT_ROOT]php:/temp) is not accessible' 

(当然 $_SERVER['DOCUMENT_ROOT'] 是真正的价值,我只是替换它):)

任何解决方案或者我必须将字体保存在文件系统中?

代码如下:

 $image = new \Imagick();
 $draw = new \ImagickDraw();

 $temp = new \SplTempFileObject();
 $temp->fwrite($font->getFile()->getContent());

 $image->newImage(550, 50, "black");
 $draw->setFont($temp);

$font 是来自数据库的数据。我认为问题是因为 ImagickDraw::setFont() 相对于 DOC ROOT 搜索字体。

【问题讨论】:

  • var_dump(is_dir($_SERVER['DOCUMENT_ROOT'].'php:/temp')) 输出什么?
  • 您能否添加显示您正在使用的代码SplTempFileObject
  • @artragis 不,这不是目录。它不应该是。我想说的是,imagick 搜索相对于文档根目录的字体。
  • 所以你想通过绝对地址访问文件?
  • @artragis 我不知道这是否是问题所在。与$draw->setFont('/'.$temp->getFileName()); 相同的问题。我想将 SplTempFileObject 与 setFont 一起使用,而不是将文件写入文件系统。

标签: php imagick


【解决方案1】:

问题是由默认使用内存缓存的 SplTempFileObject 引起的,最高可达 2MB。 \SplTempFileObject->getFileName() 将返回 php://temp \SplTempFileObject->getFileInfo() 将返回一个空对象/文件指针 \SplTempFileObject->getRealPath() 将始终返回一个空字符串!

如果您希望 PHP 在文件系统中写入真实文件,则必须提供内存限制 0 作为构造参数,但您仍然无法获得有效的 SplFileInfo 或 pathName 或 fileName 其他比php://temp/maxmemory:0

是的:这很奇怪,与创建临时文件的“简单界面”相去甚远。..

详情请关注http://php.net/manual/spltempfileobject.construct.php

返回,使用旧的tempfile()tempnam()。我的解决方案:

而不是 $file = new \SplTempFileObject();

我用 $file = new \SplFileObject(tempnam(sys_get_temp_dir(), rand()), 'w+');

【讨论】:

  • 是的,这是一个错误。
【解决方案2】:

我认为您的问题来自您的地址错误。 当您说"/".$temp->getFileName() 时,您没有根据文档获得路径。 因此,由于您没有路径,因此您的前导“/”表示“从服务器根目录”。不酷。

您可以使用getRealPath 做您想做的事。

【讨论】:

    【解决方案3】:

    正如其他人所说,\SplTempFileObject 存在一个错误,即使您将0 传递给构造函数,您仍然有一个文件在内存中,因此没有文件路径/真实路径。

    我为此构建了一个小巧简单的 PHP7+ 类:

    interface TemporaryFile {
        public function handle(\Closure $closure) : void;
        public function write(string $contents): void;
        public function getContents() : string;
        public function chmod(int $mode): void;
        public function getUri() : string; // aka realpath
        public function close() : void;
    }
    
    class IO
    {
        /**
         * @return TemporaryFile
         */
        public static function getTemporaryFile() : TemporaryFile {
            return new class implements TemporaryFile {
                private $handle;
    
                public function __construct()
                {
                    $this->handle = tmpfile();
                }
    
                public function handle(\Closure $closure) : void {
                    $closure($this->handle);
                }
    
                public function getContents() : string {
                    // according to PHP docs file_get_contents has much better performance
                    // http://php.net/manual/en/function.fread.php
                    return file_get_contents($this->getUri());
                }
    
                public function getUri() : string {
                    return stream_get_meta_data($this->handle)['uri'];
                }
    
                public function close() : void {
                    if (is_resource($this->handle))
                        fclose($this->handle);
                }
    
                public function write(string $contents): void
                {
                    fwrite($this->handle, $contents);
                }
    
                public function chmod(int $mode): void
                {
                    chmod($this->getUri(), $mode);
                }
    
                public function __destruct() {
                    $this->close();
                }
            };
        }
    }
    

    要使用它,只需这样做:

    $file = IO::getTemporaryFile();
    $file->write('foo');
    var_dump($file->getContents()); // string(3) "foo"
    

    您可以在此处看到上述示例处于工作状态:https://3v4l.org/LYfan#output

    然后你有一个临时文件,它会在进程完成或类被取消引用后自行销毁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-10
      • 2011-11-13
      • 2011-07-14
      • 2013-12-08
      • 2010-10-17
      • 2018-05-04
      • 1970-01-01
      相关资源
      最近更新 更多