как генерировать слаги в php

Я пытаюсь написать скрипт, который может переписывать URL-адреса в виде слагов, например:

http://www.mysite.com/mystorytitle/

и я сделал это в своих кодах:

 RewriteRule ^(.*)\/$  app=News&file=article&title=$1  [L] 

и в моих php-кодах я создал слаг из названия истории как:

$slug_title = mysql_real_escape_string($mtitle);
$show= "<a href=\"$slug_title/\">$mtitle</a>";

теперь все в порядке, если только, когда я не нажимаю на ссылку, она переходит на страницу, но без какого-либо стиля, javascripts и изображений.

я уверен, что проблема связана с путем для файлов css и... который был изменен на уровне

как я нахожусь на этом пути: http://www.mysite.com/%D8%A7%DB%8C%D9%85%DB%8C%D9%84/

поэтому, если страница требует файла css, как это:

<link rel="StyleSheet" href="includes/NAV.css" type="text/css" />

один уровень изменился, и чтобы это сработало, я должен вернуться на уровень как:

<link rel="StyleSheet" href="../includes/NAV.css" type="text/css" />

я думаю, это рассматривается как папка, а не переписанный путь

но я уверен, что должен быть другой способ заставить этот скрипт работать без изменения всех путей

заранее спасибо


person Mac Taylor    schedule 26.02.2010    source источник
comment
Между прочим, mysql_real_escape_string — это неправильный экран для помещения текста в HTML. Это только для запросов MySQL и не защитит вас от внедрения HTML (XSS). Вместо этого вы должны использовать htmlspecialchars вместо $mtitle. В идеале вы также должны использовать urlencode для $slugtitle, чтобы он работал как простой старый URI, а также как IRI.   -  person bobince    schedule 26.02.2010
comment
на каком основании вы говорите, что urlencode намного лучше, чем mysql_real_escape_string , кстати, при использовании urlencode он добавляет + к заголовку   -  person Mac Taylor    schedule 26.02.2010


Ответы (4)


Вы должны добавить базовый URL-адрес (в большинстве случаев косая черта, но не всегда).

Вы можете получить его следующим образом (общее выражение, которое будет работать, даже если ваш сайт находится в каталоге):

$baseUrl = rtrim((string)dirname($_SERVER['SCRIPT_NAME']), '/\\') . '/';

И тогда вы напишете:

<link rel="StyleSheet" href="<?php echo $baseUrl ?>includes/NAV.css" type="text/css" />

Другая возможность — использовать базовый тег в голове:

<base href="<?php echo $baseUrl ?>" />

Преимущество этого заключается в изменении только одной строки в вашем коде.

Вы можете пойти дальше и сделать служебный метод для этого:

function baseUrl($url = '', array $query = null, $fragment = null)
{
    static $baseUrl = rtrim((string)dirname($_SERVER['SCRIPT_NAME']), '/\\') . '/';

    if ($query !== null) {
        $url .= '?' . http_build_query($query);
    }

    if ($fragment !== null) {
        $url .= '#' . (string)$fragment;
    }

    $url = $baseUrl . $url;
    $url = trim(str_replace('\\', '/', (string)$url));

    return $url;
}
person Sagi    schedule 26.02.2010

Как вы уже писали, это произойдет потому, что браузер думает, что вы находитесь в другом каталоге, названном в честь вашего слага.

Вам нужно будет что-то сделать с URL-адресами CSS, либо ссылаться на них относительно ../includes/, как вы уже делали, либо использовать абсолютные ссылки /includes/NAV.css (доменная часть не является обязательной).

Если это проект PHP, я бы создал центральный файл настроек, содержащий корневой веб-сайт:

define("SITE_WEBROOT", "http://www.domain.com");

и ссылайтесь на все ресурсы, относящиеся к этому параметру:

<link rel="stylesheet" type="text/css" 
      href="<?php echo SITE_WEBROOT; ?>/includes/NAV.css">
person Pekka    schedule 26.02.2010
comment
это то, что я делаю, я только замкнул на <?=url?> :D - person casraf; 26.02.2010
comment
спасибо, вся моя попытка состоит в том, чтобы не так сильно меняться, если я хочу следовать вашей идее, я должен изменить более 20 ссылок на ресурсы (css,js,..), и я должен сделать то же самое для моих клиентов, которые используют мой CMS, я ищу решение, которое может отличить путь slug от пути к папке, знаете, что я говорю?! - person Mac Taylor; 26.02.2010
comment
@Mac Taylor Я понимаю, что вы говорите, но на самом деле это невозможно сделать должным образом. Это браузер считает, что он находится в другом каталоге. Вы можете создать правило перезаписи, которое перенаправляет все запросы с /slugname/includes/NAV.css на /includes/NAV.css, но это ерунда. Я думаю, что установка корневого веб-сайта — единственный выход, особенно если у вас есть CMS, которую вы отправляете клиентам. - person Pekka; 26.02.2010
comment
на самом деле я установил этот корневой веб-путь в своей cms и могу его использовать, но, как я уже сказал, все еще нужно сделать много изменений. - person Mac Taylor; 26.02.2010
comment
Вы можете использовать базовый тег в заголовке (вероятно, включенный в CMS). Он будет работать во всех случаях. Посмотрите на мой ответ. - person Sagi; 26.02.2010
comment
Я бы не стал использовать тег base, особенно если это продукт, который отправляется покупателям. Это усложняет поддержку шаблонов/страниц. - person Pekka; 26.02.2010
comment
@Mac Taylor, почему так много изменений, разве это не просто изменение нескольких ссылок на таблицы стилей? - person Pekka; 26.02.2010
comment
@Pekka это не только таблицы стилей, множество прямых ссылок на изображения или даже javascripts, .... мой текущий вопрос заключается в том, как я могу найти корневой URL-адрес веб-сайта в php, чтобы не позволять пользователям определять его - person Mac Taylor; 26.02.2010
comment
@Mac Taylor проверяет phpinfo(), чтобы определить текущий веб-корень, но что, если ваше приложение находится в подкаталоге? Вы не обойдетесь, используя определенный веб-корень. - person Pekka; 26.02.2010
comment
@Pekka на самом деле, получение базового каталога $_SERVER['SCRIPT_NAME'] работает также, если ваше приложение находится в подкаталоге. Если нет, я бы использовал \ вместо этого. - person Sagi; 26.02.2010
comment
@Sagi true, если вы находитесь в базовом каталоге своего приложения. Тем не менее, я не люблю использовать тег base, он обеспечивает быстрое решение, но имеет тенденцию вызывать проблемы в долгосрочной перспективе. - person Pekka; 26.02.2010

Просто добавьте косую черту перед всеми URI ресурсов... например, /static/image.png. Это заставит браузер запрашивать его из корня (т.е. www.site.com/path)

person aviraldg    schedule 26.02.2010

Вы также можете использовать базовый тег в разделе заголовка, тогда все относительные ссылки, таблицы стилей и изображения будут идти оттуда. Обычно мы так делаем. Он устанавливается автоматически во всех наших проектах на основе URL-адреса запроса и пути FILE файла index.php.

Например:

person douwe    schedule 26.02.2010