0

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

<?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”的文件,它位于“”的目录“dir3”下www.myurl.com/dir1/dir2/dir3,因此完整的 url 将是“ www.myurl.com/dir1/dir2/dir3/testfile.php”。

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

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

谢谢你。

4

3 回答 3

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

有关使用该$_SERVER变量的问题,请查看 PHP 手册。

// 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/"

当然,问题是你需要什么以及它有多稳定。正如所写,我完全确定,有更好的方法可以做到这一点,是的。

于 2012-05-29T13:16:21.620 回答
0

这应该有效:

$dir = $_SERVER['HTTP_HOST'] . substr(dirname(__FILE__), strlen($_SERVER['DOCUMENT_ROOT']));
于 2012-05-29T13:16:13.630 回答
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 协议。

于 2012-05-29T13:17:05.817 回答