Проблема получения корневого URL в PHP

У меня проблема с получением корневого URL с помощью этой функции PHP, которую я написал. Я могу получить это, но я должен делать исключения для каждого сервера, но вместо этого мне нужна одна последовательная функция. Можете ли вы показать мне, как это исправить?

Я помещаю его в корневую папку определенного веб-сайта, который на моей рабочей станции Ubuntu будет находиться в /var/www/website, но на моем сервере CentOS он может находиться в /home/me/website. Он работает на моей рабочей станции, но на сервере мне по какой-то причине приходится делать другую версию. Кроме того, у меня есть еще одна версия, которую я должен был сделать для еще одного сервера CentOS, который, похоже, тоже не понравился этой функции. В заключительной части этого вопроса я также перечисляю некоторую справочную информацию о том, почему я делаю это в первую очередь.

Версия рабочей станции

public function getRootURL() {
  $sTemp = str_replace($_SERVER['DOCUMENT_ROOT'],'',__DIR__);
  $sTemp = str_replace($sTemp, '', $_SERVER['REQUEST_URI']);
  $sPageURL = (@$_SERVER['HTTPS'] == 'on') ? 'https://' . $_SERVER['SERVER_NAME'] : 'http://' . $_SERVER['SERVER_NAME'];
  $sPageURL .= ($_SERVER['SERVER_PORT'] != 80) ? ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'] : $_SERVER['REQUEST_URI'];
  $sRootURL = str_replace($sTemp,'',$sPageURL);
  $sRootURL = rtrim($sRootURL, '/') . '/';
  $sRootURL = (strpos(' ' . $sRootURL, '://') === FALSE) ? $sPageURL : $sRootURL;
  return $sRootURL;
}

Версия сервера

public function getRootURL() {
  $sTemp = str_replace($_SERVER['DOCUMENT_ROOT'],'',__DIR__);
  $sTemp = str_replace($sTemp, '', $_SERVER['REQUEST_URI']);
  $sPageURL = (@$_SERVER['HTTPS'] == 'on') ? 'https://' . $_SERVER['SERVER_NAME'] : 'http://' . $_SERVER['SERVER_NAME'];
  $sPageURL .= ($_SERVER['SERVER_PORT'] != 80) ? ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'] : $_SERVER['REQUEST_URI'];
  $sRootURL = str_replace($sTemp,'',$sPageURL);
  $sRootURL = rtrim($sRootURL, '/') . '/';
  $sRootURL = (strpos(' ' . $sRootURL, '://') === FALSE) ? $sPageURL : $sRootURL;
  if (strpos(' ' . $sRootURL, 'mycentosserver.com')>0) {
    $sRootURL .= 'website/';
  }
  return $sRootURL;
}

На серверной версии обратите внимание на оператор if/then mycentosserver.com - вот в чем разница.

Альтернативная версия сервера

function getRootURL() {
  $sTemp = str_replace($_SERVER['DOCUMENT_ROOT'],'',__DIR__);
  $sTemp = str_replace($sTemp, '', $_SERVER['REQUEST_URI']);
  $sPageURL = (@$_SERVER['HTTPS'] == 'on') ? 'https://' . $_SERVER['SERVER_NAME'] : 'http://' . $_SERVER['SERVER_NAME'];
  $sPageURL .= ($_SERVER['SERVER_PORT'] != 80) ? ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'] : $_SERVER['REQUEST_URI'];
  $sRootURL = str_replace($sTemp,'',$sPageURL);
  $sRootURL = rtrim($sRootURL, '/') . '/';
  $sRootURL = (strpos($sRootURL, '://') === FALSE) ? $sPageURL : $sRootURL;
  $sRootURL .= 'website2/'; // heck, I give up -- strange Apache problem on this server
  return $sRootURL;
}

Фон

Обычно я использовал бы MVC-фреймворк, но у меня есть клиент, который хочет редактировать вещи, когда я ухожу, и который не любит MVC и не понимает его. У него есть упрощенные навыки PHP. Итак, я использую.htaccess, который выглядит следующим образом для красивых URL-адресов, и те, где косая черта может заканчиваться в конце URL-адреса, в качестве альтернативы:

Options -Indexes +FollowSymlinks -MultiViews
RewriteEngine on

#No slash on the end of the url and not a real file/folder? then show x.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[^/]*$ "$0.php" [nc]

#slashes on the end still and not a real file/folder, then remove them
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]

#if still here, and not a real file/folder, then show x.php in the alternative way
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ "$1.php" [nc]

И я создаю подпапки, такие как _css, _js, _classes и т. Д., Стараясь сделать вещи довольно простыми. Каждая страница имеет как PHP в верхней части, а затем параметры в нижней части в HTML. Это попытка устранить код спагетти. Кажется, клиенту это нравится, хотя я бы предпочел MVC, особенно по этой причине.

Однако обратите внимание, что с техникой.htaccess, есть случаи, когда мой HTML может не иметь правильного относительного пути, например, кто-то добавляет косую черту в конце URL, и поэтому я должен использовать тег в HTML, чтобы разобраться с относительной Pathing. Вот почему функция getRootURL() должна работать правильно.

2 ответа

Решение

Как насчет этого?

function getRootURL() {
  $protocol   = empty($_SERVER['HTTPS'])? 'http' : 'https';
  $servername = $_SERVER['SERVER_NAME'];
  $serverport = $_SERVER['SERVER_PORT']=='80'? '' : ':' . $_SERVER['SERVER_PORT'];
  $path       = str_replace('\\', '/', substr(dirname(__FILE__), strlen($_SERVER['DOCUMENT_ROOT'])));

  return $protocol . '://' . $servername . $serverport . $path;
}

__FILE__ должно работать, пока файл действительно находится в корне проекта (в противном случае добавьте еще несколько dirname()s.


Кстати, если вы беспокоитесь о том, что "кто-то добавляет косую черту в конце URL", почему бы вам просто не добавить /? к вашему RewriteRule?

Если я правильно понял, ваша установка CentOS находится не в корневом каталоге документов виртуального хоста, а на рабочей станции Ubuntu.

В таком случае наличие двух разных реализаций функции мне кажется вполне естественным. Просто поместите условие IF в различную ENV-переменную или SERVER_NAME и используйте одно или другое.

Другие вопросы по тегам