Как распечатать столбец с несколькими значениями в PHP

У меня есть база данных SQL Server с информацией Customer, а CustomerPhone имеет столбец с несколькими значениями, который равен C_Phone.

Это мой код:

if (!empty($_GET['customer_id'])){
    // 'id' input from the user
    $id = $_GET['customer_id'];
    // Customer Information
    $sql = "SELECT Customer.C_Code, C_FirstName, C_LastName, C_Email, C_HomeAddress, C_OfficeAddress, C_Phone
            FROM Customer, CustomerPhone
            WHERE Customer.C_code = CustomerPhone.C_code and Customer.C_code = $id;";
    $query = sqlsrv_query($conn, $sql);
    $row = sqlsrv_fetch_array($query);
    if (!empty($row)) {
        echo "
        <div class=\"card\" style=\"width: 25rem; margin-left: auto; margin-right: auto;\">
            <div class=\"card-body\">
                <h5 class=\"card-title\">Customer Information</h5>";
        echo "<p class=\"card-text\">C_code: " . $row['C_Code'] . "</p>";
        echo "<p class=\"card-text\">C_Name: " . $row['C_FirstName'] . " " . $row['C_LastName'] . "</p>";
        echo "<p class=\"card-text\">C_Email: " . $row['C_Email'] . "</p>";
        echo "<p class=\"card-text\">C_HomeAddress: " . $row['C_HomeAddress'] . "</p>";
        echo "<p class=\"card-text\">C_OfficeAddress: " . $row['C_OfficeAddress'] . "</p>";
        echo "<p class=\"card-text\">C_Phone: ";
        while($row = sqlsrv_fetch_array($query))
        {   
            echo $row['C_Phone'] . "<br>";
        }
        echo "</p>";
        echo "
            </div>
        </div>";
    }

Это результат, который я получил. Как я могу напечатать второй номер телефона под первым?

Если я выполню приведенный выше SQL-запрос в SSMS, я получу этот результат с Customer.C_Code = 7:

Главное - ваш код уязвим для SQL-инъекций. Используйте подготовленные операторы каждый раз, когда переменная должна быть помещена в запрос. Незначительная вещь - «столбец с несколькими значениями» неверен. То, что у вас есть, - это отношение один ко многим. Между ними огромная разница; первое - кошмар, а второе - правильно. К счастью, похоже, что ваши таблицы верны. Если бы вы использовали while ($row=sqlsrv_fetch_array) вместо if, вы бы получили обе строки. Чтобы получить желаемый результат, вы должны либо использовать вложенные запросы, либо использовать агрегатные функции в вашем sql.

Tim Morton 10.12.2020 05:45

@TimMorton спасибо, что указали на проблему SQL-инъекций в моем коде, раньше я этого не замечал.

huy 10.12.2020 14:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
2
218
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Есть как минимум два пути, по которым вы можете пойти. Вам придется адаптировать эти идеи к вашим функциям подключения к базе данных, так как у меня нет опыта работы с базами данных Microsoft.

Вложенные циклы

В каждой итерации информации о клиенте выполняйте второй запрос CustomerPhone, используя C_code, полученный от Customer. Как упоминалось в комментариях, используйте оператор while для повторения результатов.

while($row=sqlsrv_fetch_array($query) {

Необходимо соблюдать осторожность, чтобы внутренний запрос не затмил внешний!

Агрегатные функции SQL

Это включает в себя создание более сложного запроса. Вы можете group by поле и база данных объединяет поля:


SELECT 
     Customer.C_Code, C_FirstName, C_LastName, 
     C_Email, C_HomeAddress, C_OfficeAddress, 
     string_agg(C_Phone, ', ') AS phone
FROM Customer
INNER JOIN CustomerPhone ON Customer.C_code = CustomerPhone.C_code
WHERE
     Customer.C_code = ?
GROUP BY Customer.C_code

(обратите внимание, что в некоторых базах данных требуется, чтобы каждое поле использовалось в предложении group by)

(примечание 2. Это параметризованный запрос, который следует использовать с командой подготовки. См. документацию по подготовленным операторам. Это правильный способ использования значений в запросе)

Как показано, они будут перечислены как csv. Вы также можете использовать <br>, чтобы разделить их вместо запятой.

Ответ принят как подходящий

Причина такого неожиданного поведения заключается в том, что вам нужно вывести номер телефона клиента из первой выбранной строки (echo "<p class=\"card-text\">C_Phone: ". $row['C_Phone'] . "<br>"; вместо echo "<p class=\"card-text\">C_Phone: ";).

Вы также можете рассмотреть следующее:

  • Используйте явный синтаксис JOIN.
  • Используйте параметризованные запросы. Как упоминается в документации , функция sqlsrv_query хорошо подходит для одноразовых запросов и должна быть выбрана по умолчанию для выполнения запросов, если не применяются особые обстоятельства, а функция sqlsrv_query выполняет как подготовку операторов, так и их выполнение, и может использоваться для выполнения параметризованных запросов.

Следующий пример, основанный на вашем коде, является возможным решением вашей проблемы:

if (!empty($_GET['customer_id'])) { 
    // Customer Information
    $sql = "
        SELECT c.C_Code, c.C_FirstName, c.C_LastName, c.C_Email, c.C_HomeAddress, c.C_OfficeAddress, p.C_Phone
        FROM Customer c
        JOIN CustomerPhone p ON c.C_code = p.C_code
        WHERE c.C_code = ?;
    ";
    $params = array($_GET['customer_id']);
    $query = sqlsrv_query($conn, $sql, $params);
    if ($query === false) {
        echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);
        exit;
    }   
    // fetch data
    $row = sqlsrv_fetch_array($query);
    if (!empty($row)) {
        echo "
        <div class=\"card\" style=\"width: 25rem; margin-left: auto; margin-right: auto;\">
            <div class=\"card-body\">
                <h5 class=\"card-title\">Customer Information</h5>";
        echo "<p class=\"card-text\">C_code: " . $row['C_Code'] . "</p>";
        echo "<p class=\"card-text\">C_Name: " . $row['C_FirstName'] . " " . $row['C_LastName'] . "</p>";
        echo "<p class=\"card-text\">C_Email: " . $row['C_Email'] . "</p>";
        echo "<p class=\"card-text\">C_HomeAddress: " . $row['C_HomeAddress'] . "</p>";
        echo "<p class=\"card-text\">C_OfficeAddress: " . $row['C_OfficeAddress'] . "</p>";
        echo "<p class=\"card-text\">C_Phone: ". $row['C_Phone'] . "<br>";
        while ($row = sqlsrv_fetch_array($query))
        {   
            echo $row['C_Phone'] . "<br>";
        }
        echo "</p>";
        echo "
            </div>
        </div>";
    }
}

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