Invalid font filename (imagettfbox)

早过忘川 提交于 2019-12-18 06:56:31

问题


This question has been asked over and over but I could not find the correct answer to my problem... As a little background note, all the code was working perfectly before we moved the class file from /application/lib/class to /library/class ...

I have tried to play with GDFONTPATH, relative, absolute paths with and without the file extension to no avail. Here is some of the lines we have tried so far:

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

Multiple combination of those tries have also been used to no avail. I am really annoyed by this problem as the #1, when echo'ed gives a full path that opens up the correct font file if copy/pasted in win explorer.

It might help to know the absolute path of the file getting the error and the path of the fontname...

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

We are experiencing this problem on all dev platforms (Win, Mac and Linux) PHP 5.3.13

Thank you for your assistance.

Edit: It seems as if the file is not found / the server is not looking at the right folder... If someone could help troubleshoot the problem by pointing out how to figure out what path GD is trying to open would really help.


回答1:


We have figured out how to make it work.

To put it short, we were including the class file and then calling the methods to write the text. We were doing something like this:

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

It did not work whatever we did before or after... Until we changed the $classPath to

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

Note that they are (or should) point exactly to the same folder as the code is executed from a file in library root.

We have tried to find why absolute paths were not working but could not reproduce the bug in an isolated environment so there's something fishy with our architecture.

Thank you for your time everyone.




回答2:


I know this has been answered and accepted but I didn't see anyone chiming in on why this solution worked and what was incorrect in the first place.

The short description of the problem

The current working directory is established at the point php get's it's hands on the request and all relative paths are resolved based on the current working directory, not the directory of the file that the path is referenced in.

The long description of the problem

Relative paths in php are resolved based on the current working directory.

For testing purposes you can always see what the current working directory is by calling getcwd

This value is initially arrived at on an http request as the directory that contains the file that the web server initially handed off the request to php.

So for example if you go to http://www.mydomain.com/index.php the current working directory will be the same as the document root ($_SERVER["DOCUMENT_ROOT"])

For a CLI request the cwd is the directory you are in when you execute the command. So if I am at /home/orangepill and I run /usr/bin/php /path/to/file.php the cwd will be /home/orangepill.

This causes a problem for relative file references within included files.

Lets take this example.

  1. Client navigates to www.mydomain.com

  2. Apache has index.php set in the DirectoryIndex directive and apache finds an index.php file in the document root. Current working directory is set to the document root.

  3. /index.php contains the line include "library/myclass.php"; $_SERVER["DOCUMENT_ROOT"]."/library/myclass.php" exists and all is good

  4. myclass.php contains the line include("myclass_helper.php"); this resolves to $_SERVER["DOCUMENT_ROOT"]."/myclass_helper.php". (remember relative references resolve relative to the current working directory)

  5. $_SERVER["DOCUMENT_ROOT"]."/myclass_helper.php" doesn't exist its actually in $_SERVER["DOCUMENT_ROOT"]."/library/myclass_helper.php"

You are probably thing but wait... I've experienced different behavior in my scripts when including within an include. The reason for that is the include and require language constructs (along with a couple of other file system commands) try to include relative paths from each of the paths specified in the include path php directive. So in the above example if library directory off of the document root existed within the include paths then everything would work as expected.

A wholesale solution for requiring files relative to the current file is to structure your include paths using the __DIR__ contextual constant. So you would use include __DIR__."/myclass_helper.php"; (include dirname(__FILE__)."/myclass_helper.php in pre PHP 5.3 environments) and at runtime this would effectively convert your relative path to an absolute path based on the location of the file doing the include.

For common include directories I have gotten into the habit of specifying a few commonly used locations for use with relative file system references. for example

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

This gives you a lot of anchor points to include paths relative to.




回答3:


Have you dumped $FontName before this piece of code to debug its value?

Anyway, if you're already setting GDFONTPATH, you don't need to use any path on $FontName, in this case you could just use the font name (arialuni.ttf or even just arialuni) or at most basename() function as in your #3 example.

Your putenv() call could be just putenv('GDFONTPATH=' . realpath('../fonts')).

Try that to see if it works:

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

Update 1

Please, dump your GDFONTPATH and tell me what it prints. Add that after your putenv() call, it will force your code to raise an error with the GDFONTPATH it looked for:

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



回答4:


One may also just try to state a link relative to the root directory. I had the same problem ("Invalid file font name", function "...") and fixed it like that in the main file where the pChart is being initialized:

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

Solved the issue for me. This line USED to be like that:

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

which - I don't know why - provoked an error today.


Please note that this solution is not very elegant since it relies on the fact that your pChart folder is actually located at something like

http://myHomepage.com/files/lib

, meaning it does not work with relative directories.



来源:https://stackoverflow.com/questions/17489573/invalid-font-filename-imagettfbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!