4

这个问题被问了一遍又一遍,但我找不到我的问题的正确答案......作为一个小背景说明,在我们将类文件从 /application/lib/class 移动到 /library 之前,所有代码都运行良好/班级 ...

我曾尝试使用 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 中复制/粘贴,它会打开正确的字体文件。

了解获取错误的文件的绝对路径和字体名称的路径可能会有所帮助...

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

4 回答 4

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/';

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

我们试图找出为什么绝对路径不起作用但无法在隔离环境中重现该错误,因此我们的架构存在问题。

谢谢大家的时间。

于 2013-07-08T16:34:41.343 回答
2

我知道这已经得到了回答和接受,但我没有看到任何人插话这个解决方案为什么有效以及首先什么是不正确的。

问题的简短描述

当前工作目录是在 php get 处理请求时建立的,并且所有相对路径都是基于当前工作目录而不是引用路径的文件的目录来解析的。

问题的详细描述

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

出于测试目的,您始终可以通过调用getcwd查看当前工作目录是什么

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

因此,例如,如果您访问http://www.mydomain.com/index.php,当前工作目录将与文档根目录 ( $_SERVER["DOCUMENT_ROOT"])相同

对于 CLI 请求,cwd 是您执行命令时所在的目录。因此,如果我在/home/orangepill 并且我运行/usr/bin/php /path/to/file.phpcwd 将是/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"

您可能是这样,但是等等...当包含在包含中时,我在脚本中经历了不同的行为。原因是 include 和 require 语言结构(以及一些其他文件系统命令)尝试包含 include path php 指令中指定的每个路径的相对路径。因此,在上面的示例中,如果文档根目录之外的库目录存在于包含路径中,那么一切都会按预期工作。

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

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

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

这为您提供了很多锚点来包含相对于的路径。

于 2013-07-13T05:56:25.680 回答
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);
于 2013-07-05T17:33:29.237 回答
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

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

于 2014-09-23T16:35:22.443 回答