SplTempFileObject和Imagick

时间:2012-09-23 18:39:16

标签: php imagick

我正在使用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是来自DB的数据。我认为问题是因为ImagickDraw :: setFont()相对于DOC ROOT搜索字体。

3 个答案:

答案 0 :(得分:5)

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

如果您希望PHP在文件系统中编写真实文件,则必须提供内存限制0作为构造参数但是您仍然不会获得有效的SplFileInfo或pathName也不会除php://temp/maxmemory:0

以外的fileName

是的:这很奇怪,远离用于创建临时文件的“简单界面”..

有关详细信息,请查看http://php.net/manual/spltempfileobject.construct.php

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

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

就像其他人所说的那样,#!/bin/bash declare -A max while read -r line; do if [[ "$line" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then sub=${BASH_REMATCH[2]} subsub=${BASH_REMATCH[3]} if [[ -z "${max[$sub]}" || ${max[$sub]} -lt $subsub ]]; then max[$sub]=$subsub fi fi done < inputfile.txt for sub in ${!max[@]}; do printf "%d.%d.%d\n" 1 $sub ${max[$sub]} done 存在一个错误,即使你将\SplTempFileObject传递给构造函数,你仍然有一个内存中的文件,因此没有文件路径/ realpath

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

0

要使用它,请执行以下操作:

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

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

然后你有一个临时文件,在进程完成或类被解除引用后会自行破坏。