包含文件目录路径的完整URL

时间:2012-05-29 13:09:40

标签: php apache model-view-controller path

我一直在寻找一种方法来做到这一点,并想出了这个方法:

<?php
$script_name = $_SERVER['SCRIPT_NAME']; // to get www.myurl.com

// create a constant out of the server_name
define('HTTP_HOST', $_SERVER['HTTP_HOST'].'/');

$path_parts = pathinfo($script_name); // returns an array with path names

// get the filename with the extension
$file_name = $path_parts['filename'] . '.' . $path_parts['extension'];
// get the directory which the script lives in
$dir = rtrim($script_name, $file_name);
// trim of the left slash since it was added on the end of the HTTP_HOST constant
$dir = ltrim($dir, '/');
// store the server name and directory paths in a variable
$dir = HTTP_HOST.$dir;

echo $dir; // will return f.ex. "www.myurl.com/dir1/dir2/dir3/"

假设我有一个名为“testfile.php”的文件,它位于“www.myurl.com/dir1/dir2/dir3”目录“dir3”下,因此完整的网址将为“www.myurl.com/dir1/dir2/dir3/testfile.php”。

如果我在路径文件中声明URL加上完整目录路径的常量,或者我在f.ex我的索引文件中包含的一些配置文件,并在testfile.php中调用该常量,则回显它。它将回显“www.myurl.com/dir1/dir2/dir3/”。

我的问题是,这种方法是否可以接受,或者是否有更好的方法来实现具有指定文件的目录路径的URL?

谢谢。

3 个答案:

答案 0 :(得分:2)

众所周知,完美主义很难实现。这意味着通常有更好的方法来实现目标。

查看问题中的代码,我很确定,有更好的方法可以实现您的目标。回到你的问题:

  

我的问题是,这种方法是否可以接受,或者是否有更好的方法来实现具有指定文件的目录路径的URL?

答案是肯定的。例如,更好的方法是将实现封装到它自己的对象中,例如,文件映射器。这将使您始终能够使用可随时间变化的最佳方式。

您应该至少使用一个封装逻辑的函数来将文件名映射到web目录。还可以使用所谓的输入,并在代码的顶部处理它们:

function get_webdirectory_of_file($file)
{
   # input (and validation)

   $host = $_SERVER['HTTP_HOST'];
   $docroot = $_SERVER['DOCUMENT_ROOT'];

   if (!is_file($file) {
       throw new Exception('Not a file');
   }

   if (!$host) {
       throw new Exception('No HTTP_HOST found.');
   }

   if (!$docroot ) {
       throw new Exception('No DOCUMENT_ROOT found.');
   }  

   $len = strlen($docroot);

   if (substr($file, 0, $len) !== $docroot) {
       throw new Exception('Unable to map file out of document root to document root');
   }

   # processing

   $dir = substr(dirname($file), $len);

   # output 

   return $host . $dir;
}

由于代码位于自己的函数内部,因此您可以随着时间的推移对其进行改进,而无需更改(大部分)应用程序的其余部分。使用对象更好,因为你可以更容易地替换它使整体更灵活,但从函数开始也是一个好主意。用法示例:

 echo get_webdirectory_of_file(__FILE__);

查看您的代码:

<?php
$script_name = $_SERVER['SCRIPT_NAME']; // to get www.myurl.com

请查看PHP手册,了解使用$_SERVER变量的问题。

// create a constant out of the server_name
define('HTTP_HOST', $_SERVER['HTTP_HOST'].'/');

由于$_SERVER['HTTP_HOST']已经存在,因此无需创建常量。这只会隐藏稍后使用该常量相关的问题。我建议你从你的代码中删除那个常量。

$path_parts = pathinfo($script_name); // returns an array with path names

// get the filename with the extension
$file_name = $path_parts['filename'] . '.' . $path_parts['extension'];

实际上,你在这里寻找的是basename,就是这样:

$file_name = basename($_SERVER['SCRIPT_NAME']);

现在开始使用您的代码:

// get the directory which the script lives in
$dir = rtrim($script_name, $file_name);

这有点疼。请重新阅读rtrim函数的功能。你不想在这里使用它。

// trim of the left slash since it was added on the end of the HTTP_HOST constant
$dir = ltrim($dir, '/');

在这种情况下使用ltrim可能看起来很聪明,但通常这是一种气味,你不明白你实际做了什么以及你使用哪些输入值。与使用常量相比:

// store the server name and directory paths in a variable
$dir = HTTP_HOST.$dir;

您可以在此处重复使用变量名称($dir)。这通常没有用。另外,如果您首先添加/仅删除/上面一行,这没有任何意义。你可以放过两个。

echo $dir; // will return f.ex. "www.myurl.com/dir1/dir2/dir3/"

当然,问题在于您需要什么以及它的稳定性。如上所述,我完全相信,有更好的方法可以做到这一点,是的。

答案 1 :(得分:0)

这应该有效:

$dir = $_SERVER['HTTP_HOST'] . substr(dirname(__FILE__), strlen($_SERVER['DOCUMENT_ROOT']));

答案 2 :(得分:0)

看看是否有效:

function getCurrentPageURL() {
  $protocol = "http";
  if ($_SERVER["HTTPS"] == "on") {$protocol .= "s";}
  $protocol .= "://";

  $server = $_SERVER["SERVER_NAME"];

  if ($_SERVER["SERVER_PORT"] != "80") {
      $page = $server .  ":" . $_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
   } else {
      $page = $server . $_SERVER["REQUEST_URI"];
   }
   return $protocol . $pageURL;
}

此解决方案考虑了不同的端口和HTTPS协议。