2

別のサーバーにインストールすることになっている PHP プロジェクトがあります。プロジェクトのルート ディレクトリに名前が付けられたインクルード ファイルがあり、プロジェクト全体の複数の場所からincludes.php呼び出すことができます。インクルード ファイルには、関数がどのファイルから呼び出されたかに関係なく、プロジェクト全体の絶対 URL を返す関数が含まれています。file1.phpincludes.phpsubdir/file2.phpsubdir2/file3.phphttp://www.myserver.com/myproject/

  • $_SERVER["REQUEST_URI"]関数を呼び出すファイルのURLを返すため、使用できません(これは異なります)。この URL 関数を呼び出すことができる場所は非常に多いため、「2 つのディレクトリに移動する」などのパラメータを渡したくありません。
  • 私たちのサーバーには、のサブディレクトリにないような奇妙な構成があるため、 __FILE__andを使用できません$_SERVER['DOCUMENT_ROOT'](これは一部の人に推奨されています) 。(私は自分の学校のためにプロジェクトを書いていますが、他の学校に配布することになっています。)__FILE__$_SERVER['DOCUMENT_ROOT']

私の最後の解決策は$_SERVER["REQUEST_URI"]、ファイル部分を削除し、このディレクトリにget_headers()既知のファイル ( dummy.php) があるかどうかを確認するために使用することでした。そうでない場合は、親ディレクトリなどを確認します。残念ながら、get_headers()私たちの学校のサーバーでは何も返されません (ただし、自宅のテスト システムでは動作します)。

機能する (ただし、あまり好きではない) 解決策の 1 つは、構成ファイルにプロジェクトのルート URL を含めることです。

誰かがそれについて別のアイデアを持っていますか? 前もって感謝します!

編集: OK、自分に合った解決策を見つけました。私はまだコメントを受け付けていdebug_backtrace()ます。この機能を使用しない理由はありますか?

function urlPath()
{
    $trace = debug_backtrace();
    $first_frame = $trace[count($trace)-1]; 
    // the lowest frame gives us the filename from which the first call was made

    $callerdir = dirname($first_frame['file']);
    $includedir = dirname(__FILE__);
    $rootLength = strlen($includedir);
    $subDir = substr($callerdir, $rootLength);
    $subdirDepth = substr_count($subDir,DIRECTORY_SEPARATOR);
    // I use the fact that the include file is in the project root folder, so its 
    // folder path must be a prefix of any other file's folder path. I remove this 
    // prefix and count the number of path separators to get the "relative depth".

    $pageURL = 'http';
    if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") 
    {
        $pageURL .= "s";
    }
    $pageURL .= "://" . $_SERVER["SERVER_NAME"];
    if (isset($_SERVER["SERVER_PORT"]) && $_SERVER["SERVER_PORT"] != "80") 
    {
        $pageURL .= ":".$_SERVER["SERVER_PORT"];
    } 
    $pageURL .= $_SERVER["REQUEST_URI"];
    // I get the absolute URL of the calling page

    for ($i = 0; $i <= $subdirDepth; $i++)
    {
        $idx = strrpos($pageURL,'/');
        $pageURL = substr($pageURL, 0, $idx);
    }
    // I remove the required number of subdirectories plus one for the filename

    return $pageURL;
}
4

1 に答える 1

2

似たようなものが欲しかった。ただし、ファイル名を省略したかった。

これが仲間に役立つことを願っています!

RAW アプローチ:
これを完成させるにはしばらく時間がかかりましたが、変数を必要としない人やプロジェクトの例として残しました。あなたの状況では、グローバルにすることができます。

$current_url = (empty($_SERVER['HTTPS']) ? "http://" : "https://") . ($_SERVER['SERVER_NAME']) . (((empty($_SERVER['HTTPS']) ? 'http' : 'https') == "http" && $_SERVER['SERVER_PORT'] == 80 || (empty($_SERVER['HTTPS']) ? 'http' : 'https') == "https" && $_SERVER['SERVER_PORT'] == 443) ? "" : ":" . $_SERVER['SERVER_PORT']) . (preg_replace("!^". preg_replace("!". $_SERVER['SCRIPT_NAME'] ."$!", "", $_SERVER['SCRIPT_FILENAME']) ."!", "", __DIR__));


または、より簡単なアプローチ:)

$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
$path = substr( dirname(__FILE__), strlen($_SERVER['DOCUMENT_ROOT']));
$current_url = $protocol . $_SERVER['HTTP_HOST'] . $path;


出力例: (https、http、ポートなど)

    https://example.xyz/base/path/without/file/
    http://another.example.com/uploads/test/
    http://www.return.url:81/blah/blahblah/example/
于 2015-08-16T15:42:53.563 に答える