Как изменить запись в базе данных, когда я ввожу текст в поле ввода?

Логика такая: выводится текст из базы, рядом есть поле для ввода, после ввода текста и нажатия на ссылку "редактировать" запись в базе должна измениться. Я сделал это, только если текст статичен. Все работает. Но мне нужно взять текст из ввода. Как мне это сделать? Не могли бы вы мне помочь?

Я добавил «скрытый ввод», потому что видел аналогичные решения с ним, но не могу получить значения.

<form class = "msg-wall" method = "post" action = "/vendor/wall.php">
        <?php foreach($check_message as $row) { ?>
            <div class = "content">
                <p class = "msg"><?= $row['message'] ?></p>
                <input type = "text" name = "edit">
                <input type = "hidden" name = "id" value = "<?= $row['id'] ?>">
                <a href = "?ed=<?= $row['id'] ?>">edit</a>
            </div>
        <?php } ?>

</form>

стена.php:

if (isset($_GET['ed'])) {
    $id = $_GET['ed'];
    mysqli_query($connect, "UPDATE message SET message = 'ffffdf' WHERE id = $id");
    header('Location: ../profile.php');
}

Ваша форма настроена на нас POST, но ваш уязвимый PHP/SQL использует GET

Professor Abronsius 13.12.2020 09:07

Но я сделал ту же кнопку удаления с помощью GET-запросов и в таком виде все заработало. Я хочу использовать здесь как POST, так и GET. Разве я не могу сделать это таким образом?

Fathpath 13.12.2020 09:09

Лучше быть последовательным. Лучше установить оба как POST. С другой стороны, попробуйте использовать подготовленный оператор в обновлении БД. Похоже, вы используете цикл для получения данных из нескольких записей. Пожалуйста, используйте AJAX в вашем случае

Ken Lee 13.12.2020 09:10

Вы генерируете HTML в цикле — будет ли сгенерировано более 1 div.content? Если да, у вас есть другие проблемы

Professor Abronsius 13.12.2020 09:11

Используйте GET для получения данных и POST для обновления записей — обычно это считается практикой.

Professor Abronsius 13.12.2020 09:12

Да, будет больше 1.

Fathpath 13.12.2020 09:12

Не могли бы вы показать мне примерно, как здесь должен выглядеть запрос GET?

Fathpath 13.12.2020 09:15

Я неправильно прочитал html - подумал, что есть дубликаты идентификаторов - игнорируйте предыдущий комментарий о других проблемах.

Professor Abronsius 13.12.2020 09:16

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

El_Vanja 13.12.2020 10:45
Стоит ли изучать 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 и хотите разрабатывать...
1
9
594
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я изменил ваш код, надеюсь, это даст то, что вы хотите:

ОБНОВЛЕНИЕ: я уменьшаю область формы и создаю несколько форм для каждой строки и добавляю идентификатор строки ко всем элементам формы, и это работает для меня.

    <?php foreach($check_message as $row): ?>
    <div class = "content">
        <form class = "msg-wall" method = "post" action = "#" id = "form_<?= $row['id'] ?>">    
            <p class = "msg"><?= $row['message'] ?></p>
            <input type = "text" name = "new_message_<?= $row['id'] ?>" form = "form_<?= $row['id'] ?>">
            <input type = "hidden" name = "id" value = "<?= $row['id'] ?>" form = "form_<?= $row['id'] ?>">
            <input type = "submit" value = "Edit" form = "form_<?= $row['id'] ?>"/>
        </form>
    </div>
    <?php endforeach; ?>`

стена.php:

if (isset($_POST['id']) && isset($_POST["new_message_" . $_POST['id']])) {
    $id = $_POST['id'];
    $new_message = $_POST['new_message_' . $_POST['id']];

    mysqli_query($connect, "UPDATE message SET message = $new_message WHERE id = $id");
    header('Location: ../profile.php');
}

Ничего не изменилось, когда я ввел текст во ввод и нажал кнопку (

Fathpath 13.12.2020 09:20

Нет необходимости добавлять идентификатор к другим входным именам, если вы создаете новую форму с каждой итерацией. Это только усложнит обработку подачи. Кроме того, это все еще остается открытым для SQL-инъекций.

El_Vanja 13.12.2020 10:46

@El_Vanja Я думаю, это упростит обработку отправки, потому что этот php обрабатывает все запросы нескольких пользователей (что может произойти одновременно). Если я отправляю только идентификатор со скрытыми элементами, последнее значение new_message перезаписывает поля new_message других пользователей.

adampweb 13.12.2020 10:56

Нет. Каждый запрос пользователя обрабатывается индивидуально. Моя подача той же формы не имеет ничего общего с вашей подачей той же формы. И нет никакого способа, которым один пользователь может отправить несколько правок, когда у вас есть отдельные формы.

El_Vanja 13.12.2020 10:59
Ответ принят как подходящий

Использование GET для обновления записей в базе данных не является хорошей идеей. Запрос GET можно легко изменить, чтобы повлиять на другие записи, его можно добавить в закладки, поделиться им и т. д. Общепринятым методом обновления записей является использование POST, которое теоретически можно использовать в сочетании с GET, если действительно важно передавать переменные таким образом (например, изменение действия формы).

Исходный код уязвим для SQL-инъекций, поэтому, когда эта уязвимость существует в сочетании с запросами GET, вы недалеки от проблем. Следующие попытки снижают риски с помощью POST в сочетании с «Подготовленными заявлениями» — комментарии, сделанные в коде, должны дать дополнительную информацию.

<?php
    error_reporting( E_ALL );
    
    #db connect
    $dbhost =   'localhost';
    $dbuser =   'xxx'; 
    $dbpwd  =   'xxx'; 
    $dbname =   'xxx';
    
    try{
        mysqli_report( MYSQLI_REPORT_STRICT );
        $connect=new mysqli( $dbhost, $dbuser, $dbpwd, $dbname );
    }catch( Exception $e ){
        echo 'boom!';
    }
    
    
    if ( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['ed'], $_POST['edit'] ) ){
        # generate basic update statement with suitable placeholders
        $sql='update `message` set `message` = ? where id = ?';
        
        # create the "Prepared Statement" object
        $stmt=$connect->prepare( $sql );
        
        # bind the placeholders to variables ( these do not need to be defined at this stage with mysqli )
        $stmt->bind_param('si', $edit, $ed );
        
        # assign variables
        $edit=$_POST['edit'];
        $ed=$_POST['ed'];
        
        # commit the statement
        $stmt->execute();
        $stmt->close();
        
        # go to the winchester and have a nice cold pint
        exit( header( 'Location: ../profile.php' ) );
    }
?>
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Message Wall</title>
        <style>
            form textarea{
                border:none;
                background:whitesmoke;
                width:80%;
                height:5rem;
            }
            .content{
                width:50%;
                border-bottom:1px dotted grey;
                margin:0 0 2rem 0;
                padding:0 0 2rem 0;
            }
        </style>
    </head>
    <body>
    
        <!--
            not disclosed - the process by which the recordset / array is generated... so assumed below
            
            A single form with multiple input elements of the same name needs "Javascript"
            to aid the distinction of which records to update. The recordset is assumed to be a 
            multidimensional array created by iterating through a db query recordset.
            
            Using hidden inputs for both the message to write to db and the ID we can target
            these using "Javascript" prior to submitting the form.
        -->
        <?php
        
            # assumed method for generating recordset
            if ( $_SERVER['REQUEST_METHOD']=='GET' ){
                $sql='select * from message';
                $res=$connect->query($sql);
                $check_message=array();
                while( $rs=$res->fetch_assoc() )$check_message[]=$rs;
            }
        
        ?>
        <form class='msg-wall' method='post' action='/vendor/wall.php'>
            <?php 
                foreach( $check_message as $row ) { 
            ?>
                <div class='content'>
                    <!-- original message -->
                    <p class='msg'><?= $row['message'] ?></p>
                    
                    <!-- a Copy of original message - field will be cleared when clicked -->
                    <textarea name='edit'><?= $row['message'] ?></textarea>
                    
                    <!-- rather than a hyperlink, a button makes sense -->
                    <button type='button' data-id='<?= $row['id'];?>'>Edit</button>
                </div>
            <?php 
                } 
            ?>
            <!-- these will be updated by js prior to submission -->
            <input type='hidden' name='edit' />
            <input type='hidden' name='ed' />
        </form>
        <script>
            const form=document.querySelector('form.msg-wall');
            // for each "button" - add an event listener to watch for "click" events
            form.querySelectorAll('div.content button').forEach( bttn => {
                bttn.onclick=function(e){
                    // update the two hidden elements
                    form.querySelector('input[type = "hidden"][name = "edit"]').value=this.parentNode.querySelector('textarea').value;
                    form.querySelector('input[type = "hidden"][name = "ed"]').value=this.dataset.id;
                    
                    // for convenience in testing THIS script, the "action" attribute needs to be the SAME page... this does NOT need to be used in final version
                    form.action=location.href;
                    
                    // submit the form
                    form.submit();
                };
            });
            
            // clear the textarea if clicked but restore the value if unchanged
            form.querySelectorAll('textarea[name = "edit"]').forEach( n=>{
                n.onclick=function(e){ if ( this.value==this.defaultValue )this.value=''; };
                n.onblur=function(e){ if ( this.value=='' )this.value=this.defaultValue; };
            })
        </script>
    </body>
</html>

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