Этот вопрос задавался снова и снова, но я не мог найти правильный ответ на мою проблему … Как небольшое примечание, весь код работал отлично, прежде чем мы переместили файл класса из / 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
.
Это вызывает проблему для относительных ссылок на файлы внутри включенных файлов.
Давайте рассмотрим этот пример.
Клиент переходит на сайт http://www.mydomain.com
Apache имеет index.php, установленный в директиве DirectoryIndex, и apache находит файл index.php в корневом каталоге документа. Текущий рабочий каталог установлен в корень документа.
/index.php содержит строку include "library/myclass.php";
$ _SERVER ["DOCUMENT_ROOT"]. "/ Library / myclass.php" существует, и все хорошо
myclass.php содержит строку include("myclass_helper.php");
это разрешает $ _SERVER ["DOCUMENT_ROOT"]. "/ myclass_helper.php". ( помните, что относительные ссылки разрешаются относительно текущего рабочего каталога )
$_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
, что означает, что он не работает с относительными каталогами.