Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #21 (permalink)  
Старый 28.03.2018, 18:11
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от Sergey1986
я не могу понять алгоритм и с чего начать
Учитесь для начала анализировать код свой.

<form id="form">
while($row = mysqli_fetch_array($rs)) {
echo '

<input name="FIO" type="text" value="' . $row['FIO'] . '">
<input name="Phone" type="text" value="' . $row['Phone'] . '">
<input type="submit" value="Сохранить">
';
}
</form>

Что это будет означать - одна или множество кнопок submit в форме? Ну это же детские ошибки, по поводу которых даже не стоит обращаться на форум.

Почему не читаем что это такое mysqli_fetch_array и что она возвращает по умолчанию? Почему не запрашивается нужное или не используется mysqli_fetch_assoc, или mysqli_fetch_object в таком случае?

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

У вас бардак на сервере, а вы ищите ответ на вопрос как на клиенте отправить форму. Наведите порядок на сервере, а затем уже на клиенте ищите ответы.
Ответить с цитированием
  #22 (permalink)  
Старый 28.03.2018, 19:19
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,791

Сообщение от laimas
Что это будет означать - одна или множество кнопок submit в форме? Ну это же детские ошибки
А что криминального в том, что в форме будет несколько submit-кнопок?

<form id="form" method="post" action="handler.php">
<input type="submit" value="Сохранить">
<?php $row=mysqli_fetch_array($rs);
	foreach(array('FIO','Phone') as $key)
		echo '<input name="'.$key.'" type="text" value="'.$row[$key].'">';
?>
<input type="submit" value="Сохранить">
</form>

<script type="text/javascript">
	$('#form').submit(function(e){
		e.preventDefault();
		
		var $buttons=$(this).find('[type="submit"]').attr('disabled',true);
		$.post(this.action,$(this).serialize(),function(res){
			$buttons.removeAttr('disabled');
			
			console.log(res);
		});
	});
</script>


handler.php:
<?php

	if(
		$_SERVER['REQUEST_METHOD']!='POST' or 
		!isset($_SERVER['HTTP_X_REQUESTED_WITH']) or 
		$_SERVER['HTTP_X_REQUESTED_WITH']=='XMLHTTPREQUEST'
	)
		exit('Access denied');
		
	$fields=array_reduce(array('FIO','Phone'),function($key){
		return isset($_POST[$key])?$_POST[$key]:null;
	},array());
	
	var_dump($fields);
Ответить с цитированием
  #23 (permalink)  
Старый 28.03.2018, 19:23
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от Nexus
А что криминального в том, что в форме будет несколько submit-кнопок?
Для чего? И не проще ли простого serialize(), если по уму именовать поля формы?

mysqli_fetch_array($rs) - это полный кошмар, и для вас непростительный.

PS. И автор, и вы вслед за ним повторяете непростительную ошибку.
Ответить с цитированием
  #24 (permalink)  
Старый 28.03.2018, 21:53
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Sergey1986,
вернувшись к "я не могу понять алгоритм и с чего начать". На картинке по ссылке в общем-то совсем иная задача выполняется, поэтому ставьте задачу конкретно ваших данных и что с ними нужно делать.

Пусть у вас данные, это имя и телефон. Вот на "телефон" нужно заострить внимание. Телефон в общем-то есть уникальное значение и при добавлении записи в базу сервер должен проверять уникальность номера, не допуская дубликатов номеров. Это можно возложить и на SQL, определив полю хранящему номер уникальный индекс. Но вопрос в том как он хранится в базе. А его можно хранить как строковое значение, например так 79999999999 или так +79999999999. Это один и тот же номер, но для SQL это будут два разных значения. Поэтому уникальный индекс не в помощь и придется разбираться иначе.

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

Поля имен и телефонов при выдаче их клиенту нужно связать с этим уникальным идентификатором каждой записи в БД, которой они принадлежат. Без этого вы не сможете без ошибок не обновить данные, не удалить их, если только в условии запроса не использовать значения обеих полей (два этих значения как пара значений должны гарантировать уникальность), что будет гораздо медленнее, чем при использовании первичного ключа.

Пусть такое поле создано в таблице и имеет имя id (Примечание: без большой необходимости не используйте в именах SQL таблиц разный регистр, для MySQL что FIO, что fio, что fiO, это одно и тоже, а вот путаницы и ошибок в РНР можно получить прилично, если не следить и не помнить об этом).

Встает вопрос как связать поля с идентификаторами их записей. РНР подготавливает данные формы как массив ее полей в суперглобальных массивах. А так как массив не может иметь двух одинаковых индексов и ключей, то именовать одноименные поля формы нужно с добавлением [], индексы РНР сам расставит, согласно порядку поля в форме. По этой же причине имя списка со множественным выбором нужно именовать также - name="name[]", иначе на сервере в массив попадут значения не всех опций выбранных в нем, а только значение последней, из выбранных, опции.

Если принудительно указывать индексы в именах полей, то можно управлять порядком элементов формы в полученном на сервере массиве. А если в качестве индексов указывать идентификаторы записей, то свяжем соответствующие поля формы с их записями в базе. При этом - такое именование позволит иметь на сервере практически любую нужную структуру массива. Например, если именовать поля так:

<input name="data[1][fio]" value="A" />
<input name="data[1][phone]" value="111" />
<input name="data[2][fio]" value="B" />
<input name="data[2][phone]" value="222" />
<input name="data[3][fio]" value="C" />
<input name="data[3][phone]" value="333" />


то на сервере получим массив:

Array
(
    [data] => Array
        (
            [1] => Array
                (
                    [fio] => A
                    [phone] => 111
                )

            [2] => Array
                (
                    [fio] => B
                    [phone] => 222
                )

            [3] => Array
                (
                    [fio] => C
                    [phone] => 333
                )
        )
)


где под каждым идентификатором записи (1, 2, 3) содержатся значения ее полей fio и phone. Вообще, необходимая структура массива зависит от того, что с данными предполагается делать. Показанная выше структура удобна при обновлении записей, а для вставки записей удобнее будет многомерный массив, вложения которого, это массивы fio и phone.

Если форма, которую вы получаете нужна для редактирования записей в базе (обновление/удаление), то кроме этих полей нужно иметь еще и поле определяющее то или иное действие. Вот тут и подошли к последнему вопросу - нужны ли куча кнопок submit в форме или нет? Если предполагается обновление/удаление по одной записи, то на каждую запись (каждые два поля в форме для каждой записи) необходимо иметь две кнопки submit, с именами, например "upd" и "del", а их значениями должны быть идентификаторы записей. Но значение кнопки submit, это текст на кнопке, поэтому использовать в этом случае нужно не type submit, а button - <button name="upd" value="1">Обновить</button> <button name="del" value="1">Удалить</button>. Полям fio и phone при этом не обязательно указывать идентификатор в имени. Клиентский сценарий должен получать соответствующие выбранной кнопке поля, отправляя их вместе с ней серверу.

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

Можно писать код используя процедурный стиль даже для объектов, если это возможно. В mysqli возможны оба стиля, но хотя бы пробуйте объектный стиль, почему, понимание придет потом.

<?
//создаем объект
$dbo = new mysqli('host', 'user', 'pass', 'base_name');

//указываем поля нужные, если полей в таблице больше, и в нужном порядке
//так как мы свяжем поля с переменными для обработки результата запроса
//при этом имена полей таблицы в запросе могут не совпадать с именами переменных, в примере для поля fio
//поэтому и важен порядок полей в запросе
$sql = 'SELECT id, fio, phone FROM table ORDER BY id';

//подготавливаем запрос и проверяем
if($stmt = $dbo->prepare($sql)) {
    
    //выолняем запрос
    $stmt->execute();

    //связываем поля в запросе с переменными
    $stmt->bind_result($id, $name, $phone);
    
    echo '<form method="post">';
    //выводим форму, добавляя для полей флажок для удаления 
    while ($stmt->fetch()):?> 
        <input name="data[<?=$id?>][fio]" value="<?=$name?>" />
        <input name="data[<?=$id?>][phone]" value="<?=$phone?>" />
        <label><input type="checkbox" name="del[]" value="<?=$id?>" /> удалить</label>
    <?
    endwhile;
    echo '<button>Отправить</button><form>';
}
?>


По отправлению формы сервер получит массив data с ранее показанной структурой. Если будут выбраны флажки для удаления, то и массив del со значениями id записей, которые надо удалить. Далее простая операция по выявлению чего надо делать:

if($_POST['del']) {
    //если есть записи для удаления, вычтем их из массива обновлений
    $_POST['data'] = array_diff_key($_POST['data'], array_flip($_POST['del']));
    //делаем запрос для удаления
    $sql = 'DELETE FROM table WHERE id IN('.implode(','.$_POST['del']).')';
}

//если есть записи для обновления, обвновляем
if($_POST['data']) {
    //..... писать не буду, эту портянку пришлось писать частями в пост, ибо нет времени 
}


Все что здесь написано есть в руководстве, оно не сложно для понимания, нужно только изучать.

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

Последний раз редактировалось laimas, 29.03.2018 в 02:53.
Ответить с цитированием
  #25 (permalink)  
Старый 28.03.2018, 23:21
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,791

Сообщение от laimas
Для чего? И не проще ли простого serialize(), если по уму именовать поля формы?
В коде автора вывод нескольких кнопок - просто ошибка, однако не сложно представить ситуацию, когда несколько submito'ов в форме будут иметь смысл.
В примере js я использовал метод "serialize".

Сообщение от laimas
mysqli_fetch_array($rs) - это полный кошмар, и для вас непростительный.
Моей целью было показать автору, как можно отправить данные (js code) на сервер и на нем с ними взаимодействовать (handler.php).
PHP в представлении изменять вовсе не собирался.


Сообщение от laimas
PS. И автор, и вы вслед за ним повторяете непростительную ошибку.
Вы о строке ниже?
$row=mysqli_fetch_array($rs);
Я не стал проверять является ли $rs инстенсом mysqli_result, не проверил и является ли $row массивом.
Если у автора по поводу отрисовки формы вопросов не возникло, значит is_array($row)===true, поэтому я подзабил на этот момент, т.к. это не относилось к цели.
По-хорошему, конечно, нужно проверять вышеописанное.
В использовании процедурного стиля работы с mysqli ничего такого нет.
"mysqli_fetch_array" лучше заменить на "mysqli_fetch_assoc", если числовые ключи не нужны.

foreach(array('FIO','Phone') as $key)
        echo '<input name="'.$key.'" type="text" value="'.$row[$key].'">';
Судя по коду автора, известно, что из бд тянулись как минимум два поля.
Я отрисовывал только одну строку из бд, поэтому не вижу в этом участке чего-либо ужасного (от конкатекации можно было избавится), имена (name) полей уникальные (лучше привести их к нижнему регистру).

Про несколько сабмитов писал выше.
Ответить с цитированием
  #26 (permalink)  
Старый 29.03.2018, 00:32
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

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

Сообщение от Nexus
Вы о строке ниже?
$row=mysqli_fetch_array($rs);
Нет, это не ошибка, это вредная привычка, а силу привычки бывает сложно преодолеть. Чтобы использовать данную функцию для получения только ассоциативного набора, надо приучить себя указывать в ней требуемое, или использовать другую функцию. Это банально, но встречается, когда не задумываясь получают два набора и отдают далее, и получают на страницах дубли. А браться по оружию с другой стороны фронта предлагают как удалить их на страницах.
Глупо, но цветочки, а что если таблица содержит BLOB, и также подготавливается массив для передачи, в этом случае не хило можно нагрузить сервер расходом памяти или вообще обрушить его.
И ведь для того чтобы использовать нужное и проверять то, как вы пишите, ничего не надо.
Данная функция полезна тогда, когда, например, надо объединить в запросе поля двух таблицы имеющих одинаковые имена полей. Ассоциативный набор будет переписан полями второй таблицы, а вот индексный будет содержать поля обеих таблиц. Нужно использовать по потребности.

А ошибка в том, что разговор идет, даются советы, а похоже, что автор и сам не знает с чем придется работать, и в первую очередь с идентификацией данных, и его не спрашивают. А ведь это определяющее.
Ответить с цитированием
  #27 (permalink)  
Старый 29.03.2018, 08:14
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,791

Сообщение от laimas
а что если таблица содержит BLOB, и также подготавливается массив для передачи, в этом случае не хило можно нагрузить сервер расходом памяти или вообще обрушить его.
Думаю за этим стоит следить автору, не людям с форума.
Ответить с цитированием
  #28 (permalink)  
Старый 29.03.2018, 09:37
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от Nexus
Думаю за этим стоит следить автору, не людям с форума.
Ну так а я кому об этом изначально говорил?

Последний раз редактировалось laimas, 29.03.2018 в 09:45.
Ответить с цитированием
  #29 (permalink)  
Старый 29.03.2018, 13:26
Профессор
Отправить личное сообщение для Sergey1986 Посмотреть профиль Найти все сообщения от Sergey1986
 
Регистрация: 28.02.2018
Сообщений: 172

Ребята спасибо за ваше отзывчивость! Все верно подмечено, я на скорую руку накидал пример (и он с ошибкой), кнопка "сохранить" одна. полей от 2х до 10ти может быть. Сборку данных их формы хотел бы сделать методом serialize() и отпарвить ajax ом
Ответить с цитированием
  #30 (permalink)  
Старый 30.03.2018, 00:05
Профессор
Отправить личное сообщение для Sergey1986 Посмотреть профиль Найти все сообщения от Sergey1986
 
Регистрация: 28.02.2018
Сообщений: 172

Сообщение от laimas Посмотреть сообщение
,

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

Заранее блогадарен!
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема получения объекта JSON espltd Элементы интерфейса 13 03.02.2016 14:55
Как получить данные формы Moonlight Angular.js 0 24.10.2014 11:12
Как вывести данные из PHP Sherminator Events/DOM/Window 2 07.08.2012 20:11
Как сохранить данные из формы? Alex Danilov ExtJS 1 10.06.2012 00:53
Как подгрузить данные с чужого домена, XSS-proof? Actine AJAX и COMET 6 03.09.2011 22:08