Недопустимое имя файла шрифта (imagettfbox)

Этот вопрос задавался снова и снова, но я не мог найти правильный ответ на мою проблему … Как небольшое примечание, весь код работал отлично, прежде чем мы переместили файл класса из / 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, действительно поможет.

Мы выяснили, как заставить его работать.

Короче говоря, мы включали файл класса, а затем вызывали методы для написания текста. Мы делали что-то вроде этого:

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

Обратите внимание, что они (или должны) указывать точно в ту же папку, в которой код выполняется из файла в корне библиотеки.

Мы попытались найти, почему абсолютные пути не работают, но не могут воспроизвести ошибку в изолированной среде, поэтому есть что-то подозрительное в нашей архитектуре.

Спасибо за ваше время.

Я знаю, что на это был дан ответ и принят, но я не видел, чтобы кто-то задумывался о том, почему это решение работает и что было неправильным в первую очередь.

Краткое описание проблемы

Текущий рабочий каталог устанавливается в точке php get, это руки на запрос, и все относительные пути разрешаются на основе текущего рабочего каталога, а не каталога файла, на который указан путь.

Длинное описание проблемы

Относительные пути в php разрешены на основе текущего рабочего каталога.

В целях тестирования вы всегда можете увидеть, что представляет собой текущий рабочий каталог, вызывая getcwd

Это значение изначально поступает на http-запрос в качестве каталога, содержащего файл, который веб-сервер первоначально передал запросу на 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. Клиент переходит на сайт http://www.mydomain.com

  2. Apache имеет index.php, установленный в директиве DirectoryIndex, и 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. Причина этого заключается в том, что include и require language constructs (вместе с несколькими другими командами файловой системы) пытаются включить относительные пути из каждого из путей, указанных в директиве include php. Итак, в приведенном выше примере, если библиотечная директория с корнем документа существовала внутри включенных путей, тогда все будет работать так, как ожидалось.

Опциональное решение для требуемых файлов относительно текущего файла состоит в том, чтобы структурировать ваши пути include, используя контекстную константу __DIR__ . Таким образом, вы будете использовать include __DIR__."/myclass_helper.php"; ( include dirname(__FILE__)."/myclass_helper.php в include dirname(__FILE__)."/myclass_helper.php pre PHP 5.3), и во время выполнения это эффективно преобразует ваш относительный путь в абсолютный путь, основанный на местоположении файла, который делает include.

Для обычных включенных каталогов я привык задавать несколько часто используемых мест для использования с относительными ссылками файловой системы. например

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

Это дает вам множество опорных точек для включения путей относительно.

Вы сбросили $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 свой GDFONTPATH и скажите мне, что он печатает. Добавьте, что после вашего putenv() это заставит ваш код поднять ошибку с помощью GDFONTPATH он искал:

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

Можно также просто попытаться указать ссылку относительно корневого каталога. У меня была та же проблема («Недопустимое имя шрифта файла», функция «…») и исправлена ​​так, как в главном файле, где инициализируется 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 

, что означает, что он не работает с относительными каталогами.