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 がリクエストを取得した時点で確立され、すべての相対パスは、パスが参照されているファイルのディレクトリではなく、現在の作業ディレクトリに基づいて解決されます。

問題の長い説明

PHP の相対パスは、現在の作業ディレクトリに基づいて解決されます。

テスト目的で、getcwdを呼び出すことで、現在の作業ディレクトリが何であるかをいつでも確認できます

この値は、Web サーバーが最初にリクエストを php に渡したファイルを含むディレクトリとして、http リクエストで最初に到達します。

たとえば、http://www.mydomain.com/index.php$_SERVER["DOCUMENT_ROOT"]にアクセスすると、現在の作業ディレクトリはドキュメント ルート ( )と同じになります。

CLI 要求の場合、cwd はコマンドを実行したときのディレクトリです。したがって、私がにいて cwd/home/orangepill を実行すると、 になります。/usr/bin/php /path/to/file.php/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.phpPHP 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 に答える