字体文件名无效(imagettfbox)

时间:2013-07-05 13:01:53

标签: php gd imagettftext

这个问题一直被问到但我无法找到问题的正确答案......作为一个背景说明,在我们从/ application / lib / class中移动类文件之前,所有代码都运行良好到/ library / class ...

我曾尝试使用GDFONTPATH,相对的绝对路径,无论有没有文件扩展名,都无济于事。以下是我们迄今为止尝试的一些方法:

putenv('GDFONTPATH=' . realpath(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'fonts'));
/*1*/  $FontName = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'fonts'.DIRECTORY_SEPARATOR.basename($FontName,'.ttf');
/*2*/  $FontName = '\pChart\fonts\\'.basename($FontName);
/*3*/  $FontName =basename($FontName);
$coords = imagettfbbox($FontSize, 0, $FontName, $Text);

这些尝试的多种组合也被用来无济于事。我真的很烦恼这个问题作为#1,当echo'ed提供了一个完整的路径,如果在win explorer中复制/粘贴,则会打开正确的字体文件。

知道获取错误的文件的绝对路径和fontname的路径可能会有所帮助......

C:\wamp\www\application_bundle\Library\pChart\class\pImage.class.php
C:\wamp\www\application_bundle\Library\pChart\fonts\arialuni.ttf

我们在所有开发平台(Win,Mac和Linux)PHP 5.3.13

上遇到此问题

感谢您的协助。

编辑:似乎找不到文件/服务器没有查看正确的文件夹...如果有人可以通过指出如何找出GD试图打开的路径来帮助解决问题帮助

4 个答案:

答案 0 :(得分:2)

我们已经找到了如何使其发挥作用。

简而言之,我们包含了类文件,然后调用方法来编写文本。我们做了这样的事情:

$classPath = 'pChart/';
include($classPath.'/class/pImage.class.php');
//... inside the pImage.class we passed font like this: $FontName = $classPath.'/fonts/arialuni.ttf';
imagettfbbox($FontSize, 0, $FontName, $Text)

无论我们之前或之后做了什么都没有用......直到我们将$ classPath更改为

$classpath = '../library/pChart/';

请注意,它们(或应该)指向与从库根目录中的文件执行代码完全相同的文件夹。

我们试图找到为什么绝对路径不起作用但无法在孤立的环境中重现错误,因此我们的架构有些可疑。

感谢大家的时间。

答案 1 :(得分:2)

我知道这已经得到了回答和接受,但我没有看到任何人为什么这个解决方案有效,以及首先出现的错误。

问题的简短描述

当前的工作目录是在php得到它的请求时建立的,并且所有相对路径都是根据当前工作目录而不是引用路径的文件目录来解析的。

问题的详细描述

php中的相对路径根据当前工作目录解析。

出于测试目的,您可以通过调用getcwd

始终查看当前工作目录的内容

此值最初是在http请求中到达的,该目录包含Web服务器最初将请求传递给php的文件。

例如,如果你转到http://www.mydomain.com/index.php,当前工作目录将与文档根目录($_SERVER["DOCUMENT_ROOT"]

相同

对于CLI请求,cwd是您执行命令时所在的目录。因此,如果我在/home/orangepill并且运行/usr/bin/php /path/to/file.php,那么cwd将为/home/orangepill

这会导致包含文件中的相对文件引用出现问题。

让我们举个例子。

  1. 客户导航至www.mydomain.com

  2. Apache在DirectoryIndex指令中设置了index.php,apache在文档根目录中找到了index.php文件。当前工作目录设置为文档根目录。

  3. /index.php包含第include "library/myclass.php";行 $ _SERVER [“DOCUMENT_ROOT”]。“/ library / myclass.php”存在且一切都很好

  4. myclass.php包含行include("myclass_helper.php");这行解析为$ _SERVER [“DOCUMENT_ROOT”]。“/ myclass_helper.php”。 (记住相对引用相对于当前工作目录的解析

  5. $_SERVER["DOCUMENT_ROOT"]."/myclass_helper.php"实际上并不存在于$_SERVER["DOCUMENT_ROOT"]."/library/myclass_helper.php"

  6. 你可能只是等待......我在脚本中包含的内容中遇到了不同的行为。原因是include和require语言结构(以及一些其他文件系统命令)尝试包含include路径php指令中指定的每个路径的相对路径。因此,在上面的示例中,如果文件根目录中的库目录存在于包含路径中,那么一切都将按预期工作。

    需要相对于当前文件的文件的批发解决方案是使用__DIR__上下文常量构建包含路径。因此,您将在PHP 5.3之前的环境中使用include __DIR__."/myclass_helper.php";include dirname(__FILE__)."/myclass_helper.php),并且在运行时,这将根据执行包含的文件的位置有效地将您的相对路径转换为绝对路径。

    对于常见的包含目录,我养成了为相关文件系统引用指定一些常用位置的习惯。例如

    define ("APPLICATION_PATH", realpath($_SERVER["DOCUMENT_ROOT"]."/application");
    define ("LIBRARY_PATH", realpath($_SERVER["DOCUMENT_ROOT"]."/library");
    define ("CONFIG_PATH", APPLICATION_PATH."/etc/";
    

    这为您提供了许多锚点,以包含相对于的路径。

答案 2 :(得分:0)

您是否在这段代码之前转储$FontName以调试其值?

无论如何,如果您已经设置GDFONTPATH,则无需在$FontName上使用任何路径,在这种情况下,您只需使用字体名称( arialuni.ttf 或甚至只是 arialuni )或最多basename()功能,如#3示例所示。

您的putenv()来电可能只是putenv('GDFONTPATH=' . realpath('../fonts'))

试试看它是否有效:

putenv('GDFONTPATH=' . realpath('../fonts'));
$FontName = 'arialuni.ttf'; // note that I'm using font name directly
$coords = imagettfbbox($FontSize, 0, $FontName, $Text); 

更新1

请转储您的GDFONTPATH并告诉我它打印的内容。在putenv()调用后添加该代码,它会强制您的代码在其查找的GDFONTPATH引发错误:

 trigger_error(sprint('GDFONTHPATH = %s', getenv('GDFONTPATH')), E_USER_ERROR);

答案 3 :(得分:0)

也可以尝试声明相对于根目录的链接。我遇到了同样的问题("无效的文件字体名称",功能" ...")并将其修改为正在初始化pChart的主文件中的那个:

$myPicture->setFontProperties(array("FontName"=>$_SERVER['DOCUMENT_ROOT']."/files/lib/pChart/fonts/verdana.ttf"));

为我解决了这个问题。 使用的这条线是这样的:

$myPicture->setFontProperties(array("FontName"=>"fonts/verdana.ttf"));

- 我不知道为什么 - 今天引发了错误。


请注意,此解决方案不是很优雅,因为它依赖于您的pChart文件夹实际位于

的事实
http://myHomepage.com/files/lib

,意味着它不适用于相关目录。