Форум программистов, компьютерный форум, киберфорум
Наши страницы
PHP: базы данных
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.91
sergei1094
0 / 0 / 0
Регистрация: 28.01.2016
Сообщений: 17
#1

Можно ли писать sql запросы в цикле? - PHP БД

28.01.2016, 22:50. Просмотров 3921. Ответов 31
Метки нет (Все метки)

Говорят что это не правильно писать sql запросы в цикле, но как обходить такие случаи?

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function StartID($connect, $data, $cat) {
 
    $sql = mysqli_query($connect, "SELECT * FROM `users` WHERE `cat` = '$cat' ORDER BY `time` ASC LIMIT 1");
 
    if(mysqli_num_rows($sql) > 0) {
 
        $res = mysqli_fetch_array($sql);
        $poz = $res['poz'];
        $time = time();
 
        if(!empty($data)) {
 
                mysqli_query($connect, "UPDATE `users` SET `time` = '$time' WHERE `poz` = '$poz'");
                mysqli_query($connect, "UPDATE `online` SET `poz` = '$poz' WHERE `id` = '$data'");
 
        }
    }
}

http://www.cyberforum.ru/php-database/thread928427.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.01.2016, 22:50
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Можно ли писать sql запросы в цикле? (PHP БД):

Запросы к БД в цикле или большой объем в памяти
Вопрос от новичка: сейчас делаю обновление товаров в интернет магазине. В...

SQL запросы
Раньше я использовал php и дело не доходило до баз данных и sql. Работать с...

SQL запросы
Здравствуйте, с недавних пор начал задумываться о безопасности( SQL ijection),...

SQL запросы
Нужна помощь, крч у меня вот такой запрос: $query3 =...

SQL запросы
Здраствуйте! Есть данные в таблице(themes) надо их считать в виде таблицы на...

31
sergei1094
0 / 0 / 0
Регистрация: 28.01.2016
Сообщений: 17
29.01.2016, 20:01  [ТС] #21
Конечно же мне ничего не мешает эту же функцию вставить в функцию ООП. Сейчас просто мне хочется именно понять процедуру GROUP_CONCAT


Вот так выводится процедурная функция:
0
Миниатюры
Можно ли писать sql запросы в цикле?  
wolfalone
В экстазе
164 / 148 / 38
Регистрация: 05.08.2012
Сообщений: 754
Записей в блоге: 3
29.01.2016, 20:41 #22
sergei1094, у Вас есть возможность отказаться от phpMyAdmin? Если есть - настоятельно рекомендую использовать "настольную" программу для работы с базой, например HeidiSQL, MySQL Workbench или какую-либо другую, на Ваш выбор.

Что бы было проще ответить на Ваш вопрос - пришлите скриншот с запросом и кусочком результатов выборки, что бы можно было визуально представить, откуда растёт источник проблем... (*несколько подобных скриншотов я выкладывал ранее, можно их использовать в качестве образца)
1
sergei1094
0 / 0 / 0
Регистрация: 28.01.2016
Сообщений: 17
30.01.2016, 00:48  [ТС] #23
Предыдущий вопрос решил, тренировками запоминаю. Спасибо большое Вам


Вот тут ещё вопросик у меня есть по ООП. Создал класс с подключением к БД и функцию обновления данных пользователей.

Вот класс:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class DB {
 
    protected $db_name = 'pro';
    protected $db_user = 'root';
    protected $db_pass = '';
    protected $db_host = 'localhost';
    
    public function connect() {
        $connection = mysqli_connect($this->db_host, $this->db_user, $this->db_pass, $this->db_name);
                            mysqli_query($connection, 'SET NAMES UTF8');
    return $connection;
    }
 
 
 
    public function update($connection, $data, $table, $where) {
   
        foreach ($data as $column => $value) {
            
            $sql = "UPDATE $table SET $column = $value WHERE $where";
            mysqli_query($connection, $sql) or die('Ошибка подключения Базы Данных!');
        }
    return true;
    }
    
}

А вот тут я вызываю сам класс, подключение к БД и пытаюсь обновить данные в БД:

PHP
1
2
3
4
5
6
7
8
$db = new DB();
$db->connect();
 
$data = array(
            "name" => "'admin'",
            "pass" => "'admin'");
 
$db->update($connection, $data, 'users', 'id = 1');
Но что бы я не делал, как бы не пытался играться с переменной $connection, у меня постоянно выводится ошибка следующего типа:

Oracle 11 SQL
1
2
Warning: mysqli_query() expects parameter 1 TO be mysqli, NULL given IN C:\OpenServer\domains\chat\classes\db.php ON line 20
Ошибка подключения Базы Данных!

А если помещаю тело функции connect в тело функции update, то скрипт выполняет должные действия. Что я не так делаю?
0
wolfalone
В экстазе
164 / 148 / 38
Регистрация: 05.08.2012
Сообщений: 754
Записей в блоге: 3
30.01.2016, 01:20 #24
Лучший ответ Сообщение было отмечено sergei1094 как решение

Решение

sergei1094, первое, на что сразу хочу обратить Ваше внимание - я бы порекомендовал сделать следующие корректировки:
1. Создать классу конструктор и передавать в него параметры подключения к БД, например так:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class DB {
 
    protected $login;
    protected $password;
    protected $host;
    protected $connection;
    
    public function __construct($login = 'login', $password = 'password', $host = 'localhost') {
        $this->login = $login;
        $this->password = $password;
        $this->host = $host;
        $this->connection = mysqli_connect($this->host, $this->login, $this->password);
    }
    
    public function update($table, $data, $condition) {
        mysqli_query($this->connection, "QUERY");
    }
 
}
Передавать "коннекшен" из вне, я думаю не стоит. Если нам нужно 2 соединения с БД, достаточно создать два экземпляра класса DB().

Я думаю, такой прототип класса выглядит немного красивше

Добавлено через 10 минут
ещё из функции UPDATE неплохо бы возвращать кол-во затронутых строк, сделать там генерацию запроса, в т.ч. условие ($condition) сделать массивом, по принципу:
PHP
1
2
3
4
$condition = array(
    ['id', '>', '0'], //ID больше нуля
    ['user_id', 'IS NOT', 'NULL'], //ID_пользователя не равен NULL
)
и так далее...

а так же добавить кучу других функций, и тогда у нас получиться... Свой, маленький ORM, т.е. Object Relation Mapper, то есть штука, которая позволяет "проецировать" (примерно так же, как это делает видео-проектор) таблицы на PHP-классы. То есть, говоря более простым языком, "штука которая позволяет представлять таблицы в виде классов/объектов", со всеми вытекающими

Кстати, таких штук есть целая куча готовых. В т.ч. в каждом PHP-фреймворке есть либо своя реализация чего-то подобного, либо, уже прикрученная сторонняя библиотека, например Doctrine или Propel.

Это я к тому, что бы не получилось как в камеди-клабе: Нас изначально приучают к бедности... что мы делаем на уроках труда?! Табуретки! Они не говорят, что табуретки уже есть готовые и их можно купить!

Добавлено через 8 минут
Да, и если функция update() должна изменять только данные пользователя (а не что-то ещё), то я бы пожалуй предложил её тоже модифицировать немного. Для индентификации пользователя, можно/нужно передавать его ID или допустим логин (или если логин не может состоять только из цифр, то переавать "ID или логин" и проверять, что передали, например с помощью функции is_numeric(), если цифра - значит ID, если нет - значит логин). А вторым параметром передавать массив по принципу поле-значение, с данными которые у пользователя нужно изменить...

т.е. выглядеть функция будет примерно так:
PHP
1
public function update($id_or_login, $data = array()) { }
1
sergei1094
0 / 0 / 0
Регистрация: 28.01.2016
Сообщений: 17
30.01.2016, 02:22  [ТС] #25
Благодарю за наставления. А вот скажите, мне теперь постоянно нужно передавать параметры в конструктор при вызове функции?

т.е.

PHP
1
2
3
4
... __construct($login = 'login', $password = 'password', $host = 'localhost')
----
...
$db = new dbConnect($login, $password, $host, $db_name);
Я вот видел что многие используют подключение на страницах вот примерно так:
PHP
1
2
$db = new dbConnect();
и поехали....
Я пересмотрел ваши примеры, а затем пересмотрел свой, тот же пример. Свою проблему я решил вот так:

Раньше при подключении к БД делал так:
PHP
1
2
3
4
5
6
7
8
9
$db = new DB();
$db->connect();
//Ругается
 
//А потом сделал вот так:
$db = new DB();
$connection = $db->connect();
 
//Выполнилось условие
Но вот как быть теперь? Я вам уже так доверился И конечно же хочется использовать правильное написания классов и их методов, но ещё хочется использовать удобные конструкции для их использования
Если бы было всё так как мы хотим
0
wolfalone
В экстазе
164 / 148 / 38
Регистрация: 05.08.2012
Сообщений: 754
Записей в блоге: 3
30.01.2016, 02:39 #26
Лучший ответ Сообщение было отмечено sergei1094 как решение

Решение

Если очень хочется, то мы можем вынести функцию connect() отдельно, тогда её код будет выглядеть примерно так:

PHP
1
2
3
public function connect() {
    $this->connection = mysqli_connect($this->host, $this->login, $this->password);
}
Но, в том примере который я привёл - подключение происходит сразу же, при создании класса (в конструкторе). Я думаю, сразу подключаться к БД при создании класса для работы с БД в данном случае логично, при этом, делать это БЕЗ вызова доп функций, типа connect().

Цитата Сообщение от sergei1094 Посмотреть сообщение
$connection = $db->connect();
Зачем нам ссылка на соединение за пределами класса? Оно, по логике, должно использоваться внутри класса там же и оставаться.

То есть, в примере который я приводил выше, выглядеть всё будет примерно так:
PHP
1
2
$db = new DB(); //Создаём класс для работы с БД
$db->update(...); //Обновляем данные пользователя. По такому же принципу, выполняем все остальные операции
То есть, при создании класса DB, мы уже подключены к базе, и дополнительно вызывать метод connect() нам уже не требуется.
1
sergei1094
0 / 0 / 0
Регистрация: 28.01.2016
Сообщений: 17
30.01.2016, 04:41  [ТС] #27
Цитата Сообщение от wolfalone Посмотреть сообщение
То есть, при создании класса DB, мы уже подключены к базе, и дополнительно вызывать метод connect() нам уже не требуется.
Ещё раз огромное вам спасибо Такой метод действительно очень даже удобный
Я вам ещё не надоел? Если нет, прошу вас ещё меня направить в правильную сторону

Вот функция SELECTA:

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public function select($data, $table, $where) {
 
        $sql = mysqli_query($this->connect, "SELECT $data FROM $table $where");
        
        if(mysqli_num_rows($sql) > 0) {
            
            $arr = mysqli_fetch_array($sql);
            
 
                //Какая то логическая операция
  
        } else return false;
        
        return true;
    }
Логично ли использование такой функции вообще? В будущем просто хотелось бы не писать постоянно эти select'ы, а обращаться к ним по определённым нуждам.
Например:
Сейчас пытаюсь с нуля сделать авторизацию юзера. Проблем то никаких конечно нет с её созданием, но при авторизации юзера, когда он вводит логин и пароль, я бы хотел сравнивать эти значения сразу в запросе

PHP
1
2
3
4
5
6
DB_class
 
SELECT....WHERE `login` = '$post_login' AND `pass` = '$post_pass'
 
//$post_login и $post_pass передающиеся от ПОСТ запроса
//Далее обработки и всё такое...
Ну и соответственно класс авторизации
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Auth {
 
    private $name;
    private $pass;
    
    public function logIn($name, $pass) {
        
        $this->name = $name;
        $this->pass  = $pass;
        
         // Вот сюда я подставляю запрос селект и делаю выборку
         $db->select($connect, "`name`", "`users`", "WHERE `id`='1'");
 
         //В самом $db->select(....); я проверяю на [B]true[/B] or [B]false[/B]
 
        //Теперь тут же я хочу узнать, true вернул SQL или false
        //И если вернулась правда, то продолжаю логическую операцию с присваиванием сессий и т.д.
        //Затем авторизация и Location на (куда-нибудь);
 
               
    }  
}
Логична ли сама задача? Этот селект хотелось бы конечно использовать не только для авторизации, но и например для вывода какого то будущего (пока не определённого мною ) списка и т.п.

Добавлено через 8 минут
Цитата Сообщение от sergei1094 Посмотреть сообщение
$db->select($connect,

не $db->select($connect...

а $db->select($this->connect...

Ещё не всё переделал, даже не заметил
0
wolfalone
В экстазе
164 / 148 / 38
Регистрация: 05.08.2012
Сообщений: 754
Записей в блоге: 3
30.01.2016, 05:12 #28
Лучший ответ Сообщение было отмечено sergei1094 как решение

Решение

Цитата Сообщение от sergei1094 Посмотреть сообщение
Логично ли использование такой функции вообще? В будущем просто хотелось бы не писать постоянно эти select'ы, а обращаться к ним по определённым нуждам.
Почему нет? Если класс соответствует нуждам, значит он "логичен"

Вообще, конечно, я бы обратил Ваше внимание на несколько особенностей написания кода.

Например, тут:
Цитата Сообщение от sergei1094 Посмотреть сообщение
} else return false;
если изначально в условном операторе if были открыты фигурные скобки { }, то лучше (нагляднее), и далее следовать такому же синтаксису, т.е.
PHP
1
2
3
4
5
if (condition) {
//...
} else { //так же, через { } (фигурные скобки)
 
}
Обычно, FALSE -- означает "провал" операции, т.е. например, неудачную попытку авторизации.

В примере выше, который:
Цитата Сообщение от sergei1094 Посмотреть сообщение
public function select($data, $table, $where) {
при условии, что после условного оператора if возвращается значение -- else можно вообще удалить, и сделать reutrn внутри тела if (после return функция перестанет выполняться и вернёт значение, не зависимо от того, что прописано далее.

Так же неплохо было бы, обрабатывать данные полученные из форм, на предмет того, что бы они не превратились в SQL-инъекцию (это в качестве, например логина, "злоумышленник" вводит SQL-код запроса.

Цитата Сообщение от sergei1094 Посмотреть сообщение
не $db->select($connect...
а $db->select($this->connect...
по идее, "подключение" к самой БД должно храниться внутри класса для работы с БД, я уже писал об этом выше

И много-много других мелких замечаний

Я думаю, Вам стоит попробовать поизучать CodeIgniter, по следующим, признакам и показателям:
1. Он довольно таки простой и достаточно примитивный
2. Его просто учить и он не уводит в сторону такими вещами как консоль и команды, пространства имён и так далее
3. В нём есть ORM (т.е. класс для работы с БД), который как раз таки очень похож на то, что Вы пытаетесь сделать. Оттуда можно будет почерпнуть несколько полезных практик написания подобных классов
4. Там нет авторизации (по крайней мере, не было. И даже если есть, то ничего не мешает написать её самому), как раз можно будет потренироваться в её написании
5. Он представляет модель MVC - Модель Вид Контроллер, один из основополагающих столпов в разработке ПО, особенно для веба. Знать его просто необходимо.
6. У него есть документация на русском (ссылка на содержание -- сверху справа) и на ютубе должна быть масса примеров и уроков
7. Ну и масса других достоинств. Хотя, пожалуй, самое важное из них я уже озвучивал... Он не уводит далеко в сторону от понятия "программирование" к понятию "создание", т.е. он достаточно близок к "корням" и не изобилует всякими модными понятиями типа "Dependecy injection" (внедрение зависимостей) и другими, позволяя сначала понять, чего не хватает в работе, что бы потом хорошо понимать, зачем эти всякие термины и методики ввели.

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

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

Модель - эта штука, в которой обычно либо хранятся все запросы, либо она может являться просто ссылкой на таблицу в БД и содержать в себе просто параметры этой таблицы, такие как: связи с другими таблицами, описание полей, данные для валидации и т.д.

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

Попробуйте
1
sergei1094
0 / 0 / 0
Регистрация: 28.01.2016
Сообщений: 17
30.01.2016, 08:08  [ТС] #29
Цитата Сообщение от wolfalone Посмотреть сообщение
Попробуйте
Хорошо) Спасибо Сейчас почитаем то, что порекомендовали именно вы

Добавлено через 1 час 51 минуту
Очень даже интригующий своему вниманию фрэймворк. Спасибо за напрвление +10
0
wolfalone
В экстазе
164 / 148 / 38
Регистрация: 05.08.2012
Сообщений: 754
Записей в блоге: 3
30.01.2016, 08:59 #30
Цитата Сообщение от sergei1094 Посмотреть сообщение
Очень даже интригующий своему вниманию фрэймворк. Спасибо за напрвление +10
Рад, что Вам он понравился
1
sergei1094
0 / 0 / 0
Регистрация: 28.01.2016
Сообщений: 17
01.02.2016, 17:40  [ТС] #31
Цитата Сообщение от sergei1094 Посмотреть сообщение
wolfalone
Доброго вам вечера, вы мне не подскажете, в чём может у меня заключаться ошибка?

есть Ajax отправляющий данные в test.php в формате JSON, и соответственно его обработчик.

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function DeleteUs(data) {
 
    var user = data;
    var pass;
    var title = "Введите пароль администратора";
    var result = prompt(title, pass);
    
    if(result) {
        
        $.ajax({
            url: "/test.php",
            type: "POST",
            data: {password: result},
            dataType: 'json',
            success: function (data) {
                
                var result = data;
                alert(result.id);
                console.log(result.id);
                
            }
        });    
    }
}
сам php:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?
header('Content-type: application/json; charset: utf-8');
 
$connect = mysqli_connect("localhost", "root", "", "taxi") or die('error');
mysqli_query($connect, "SET NAMES UTF8");           
 
require_once 'test/functions.php';
 
 
if(isset($_POST['password'])) {
    
    $data = array(
                "status" => 1,
                "id" => $_POST['password'],
                 );
    
    echo json_encode($data);
    exit();
}
?>

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

PHP
1
2
3
4
$connect = mysqli_connect("localhost", "root", "", "taxi") or die('error');
mysqli_query($connect, "SET NAMES UTF8");           
 
require_once 'test/functions.php';
То данные и отправляются и принимаются. Изначально думал что дело в BOM, но проверив кодировку, всё в порядке. Так же, если раскомментировать

PHP
1
2
$connect = mysqli_connect("localhost", "root", "", "taxi") or die('error');
mysqli_query($connect, "SET NAMES UTF8");
...то аякс тоже перестаёт отправлять данные. Так же, если закомментировать обратно коннект с базой и раскомментировать инклуд, аякс опять же перестаёт отправлять данные. Куда копать, подскажите?
0
wolfalone
В экстазе
164 / 148 / 38
Регистрация: 05.08.2012
Сообщений: 754
Записей в блоге: 3
02.02.2016, 07:08 #32
Цитата Сообщение от sergei1094 Посмотреть сообщение
Дело в том, что данные не отправляются аяксом в сам обработчик, но если закомментировать вот эти строки:
Точно диагностировать ошибку я к сожалению не могу (возможно от части по тому, что по утрам я чувствую себя как овощ ), но могу сказать, в какую сторону стоит посмотреть...

И так, давайте по порядку...

Для начала, Вам стоит убедится, что данные отправляются внутри одного и того же домена, так как (цитата с какого-то сайта):
Суть проблемы была в следующем: мне нужно было, чтобы мой скрипт отправлял с нескольких сайтов запросы на один сервер, собирающий некоторые данные. Политика безопасности браузеров запрещает это делать через обычный XHTTPRequest.
То есть, Ваш браузер не позволит отправить AJAX-запрос с одного сайта, на другой.

Второй важный момент: все запросы, не зависимо от того, каким форматом они представлены, можно посмотреть в браузере. И не только запросы сами запросы, но и все подробности. Включая "тело" запроса, ответ, код ответа и так далее. В Chrome & FireFox это можно сделать нажав F12 и открыв соотв. вкладку отладочной панели. Как делается в других браузера не подскажу, но точно знаю, что что-то подобное было и в IE и Opera и где-то ещё.

Соответственно, воспользовавшись панелью отладки, Вы сможете точно определить:
1. Уходит ли запрос вообще
2. Пытается ли он уйти, или падает из-за какой-то ошибки (выполнение JS-скрипта, прекращается с той точки, в которой обнаружена ошибка и не продолжается до конца всего скрипта, по этому, крайне важно мониторить ошибки JS)
3. Если ошибка возникает в PHP-коде, Вы можете её увидеть в двух местах: А) В результате ответа на запрос (при просмотре запроса и результатов его выполнения) или в самом браузере Б) В логах Вашего сервера.

Диагностировать ошибки Вам придётся очень часто и порой очень большие и не редко ошибки могут отображаться вообще не в тех местах, где они возникли (например, Вы писал код в контроллере, а ошибка произошла в каком-то системном файле фреймворка на строке строке 5457). По этому, умение "отлавливать" ошибки, как навык, Вам очень пригодится (так же как и отладчики, и прочие инструменты в этой работе). В виду чего, предлагаю попробовать Вам диагностировать ошибку в качестве тренировки, а потом написать непосредственно код и/или сообщение об ошибке, что бы мы могли её разобрать.
0
02.02.2016, 07:08
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.02.2016, 07:08
Привет! Вот еще темы с решениями:

sql запросы
запросы типа: CREATE ALTER INDEX DROP это же аналог того, что мы...

Множественные sql запросы
Здравствуйте. Возможно ли осуществить множественный sql запрос по типу (как...

sql запросы и работа с ними
Всем привет! Есть база данных с тремя столбцами. Подскажитеподалуйстч, как...

sql запросы и переменные php
Добрый день. У меня есть вот такой фрагмент кода, который должен брать id из...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru