Очистка пробелов в сгенерированных параметрах URL-адреса

#javascript #php #html

Вопрос:

У меня проблема со страницей PHP, которая генерирует HTML-документ. На странице есть форма, в которой есть <select> поле, и каждая <option> внутри имеет значение с параметрами URL, которые будут использоваться при изменении расположения окна, когда форма «отправлена». Проблема в том, что я заметил, что одним из параметров является имя, и когда в этом имени есть пробел, оно нарушает расположение окна, потому что пробел остается в URL-адресе.

Я попытался просто выполнить a str_replace() в строке, прежде чем она создаст <option> тег, и когда я просматриваю инспектор <option> в Firefox, он действительно содержит a вместо пробела , но когда я смотрю на строку URL после нажатия <option> , она все еще сохраняет пробел вместо . Кто-нибудь может сказать мне, что не так со следующим фрагментом?

 print("<form name=sel1>");
print("<select size=10 style='width:200;font-family:courier,monospace;
        font-weight:bold;color:black;' ");
print("onchange="location = this.options[this.selectedIndex].value;">");
for($i = 0; $i < count($allGroups); $i  )
{
    print("<option value='groups.php?action=");
    if($advancedPermissions)
    {
        if($modGroups)
        {
            print("edit");
        }
        else
        {
            print("view");
        }
    }
    else
    {
        print("edit");
    }
    print("amp;group_id=");
    print(str_replace(" ", " ", $allGroups[$i][0])."'>");

    print($allGroups[$i][0]);
    if($allGroups[$i][2] != 'Y')
    {
        print(" - inactive");
    }
}

print("</select></form>");
 

Соответствующие строки-это строка с location = и строка сразу после group_id добавления параметра, в которой str_replace() выполняется.

Я str_replace() использую только значение, а не отображаемый текст, поэтому он будет отображаться нормально для пользователя, но содержит символ, когда он передается в расположение окна, но независимо от этого он либо игнорирует его, либо происходит что-то еще, о чем я не знаю.

Комментарии:

1. Используйте функции PHP сначала trim (), а затем str_replace (» » ,» -«, $location), попробуйте !

2. @Sanmeet Я не могу заменить его тире, так как в некоторых идентификаторах групп есть тире. Это должно быть . Но я также должен удалить этот , если это не произойдет автоматически, когда страница PHP получит эти данные, чтобы я мог сопоставить параметр group_id с информацией, поступающей из базы данных.

3. Ладно, ладно, это непросто.

4. 1. Избавьтесь от этого str_replace() и используйте либо urlencode() или rawurlencode() . 2. Строка URL-адреса лежит и почти всегда показывает вам расшифрованную, удобную для человека версию URL-адреса. 3. Действительно правильный ответ http_build_query() , как в примере микена, но это зависит от того, насколько вы мотивированы, чтобы убрать часть этого беспорядка, а не поднимать руки в воздух и говорить: «Ну, я этого не писал…».

5. @Sanmitch Нет, я определенно собираюсь попробовать http_build_query, но я имел в виду его предложение переписать всю страницу в соответствии с его предпочтительным форматом. Это было бы неплохо, но у меня нет ни времени, ни причин.

Ответ №1:

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

Вы должны создавать строки HTTP-запроса с помощью http_build_query() функции, которая будет обрабатывать проблемы с экранированием, подобные той, которая у вас есть, и вы всегда должны экранировать HTML для вывода с помощью htmlspecialchars() .

print обычно не используется, но обратите внимание, что это языковая конструкция, а не функция. Круглые скобки не нужны и используются редко.

Встроенные объявления CSS и JavaScript очень популярны в 20 веке, и их следует избегать везде, где это возможно.

Вот как я бы начал переработку этого кода…

 <?php
// assuming $allGroups is created in a loop
// the following code could be incorporated into that loop
$options = [];
foreach ($allGroups as $group) {
    $action = ($advancedPermissions amp;amp; !$modGroups) ? "view" : "edit";
    $group_id = $group[0];
    $url = "groups.php?" . http_build_query(compact("action", "group_id"));
    $options[$url] = $group[0] . ($group[4] !== "Y" ? " - inactive" : "");
}


?>
<!doctype html>
<html>
<head>
    <style>
        #location_select {
            width: 200px; font-family: monospace; font-weight: bold; color: black;
        }
    </style>
</head>
<body>
    <form name=sel1>
        <select id="location_select" size="10">
    <?php foreach ($options as $value => $option): ?>
            <option value="<?= htmlspecialchars($value) ?>">
                <?= htmlspecialchars($option) ?>
            </option>
    <?php endforeach ?>
        </select>
    </form>

    <script>
        document
            .getElementById("location_selector")
            .addEventListener("change", function() {
                window.location = this.options[this.selectedIndex].value;
            });
    </script>
</body>
</html>
 

Но если вы ищете быстрое решение:

 for($i = 0; $i < count($allGroups); $i  )
{
    $action = ($advancedPermissions amp;amp; !$modGroups) ? "view" : "edit";
    $group_id = $allGroups[$i][0];
    $url = "groups.php?" . http_build_query(compact("action", "group_id"));
    print("<option value='$url'>");
    print($allGroups[$i][0]);
    if($allGroups[$i][2] != 'Y')
    {
        print(" - inactive");
    }
    print("</option>");
}

 

Комментарии:

1. Ну, хотя ваши комментарии о дизайне приятны, это унаследованный мной устаревший код, и я просто пытаюсь реализовать новую функцию. У меня нет времени на рефакторинг всего сайта. Страница должна создаваться динамически, поскольку то, что находится на странице, зависит от данных базы данных и параметров URL. Я попробую http_build_query и htmlspecialchars.

2. Ну, минимальное исправление состояло бы в том, чтобы взять первые 3 строки моего цикла и использовать их в верхней части вашего цикла для правильного построения URL-адреса. Я обновил свой ответ, чтобы включить это. htmlspecialchars() вряд ли это повлияет на конкретную проблему, с которой вы столкнулись, но, очевидно, рекомендуется лучшими практиками.

3. Оказывается, пространство в идентификаторе группы не было проблемой… Я заметил, что у меня есть логическое условие, из-за которого страница не создает представление информации, и я не мог вспомнить, с какой целью я его туда поместил, но в принципе, любой идентификатор группы с пробелом в нем приведет к остановке создания страницы. Не знаю, зачем я это сделал, но… ну что ж, теперь это работает. Спасибо!