База данных mySQL - как правильно подключиться и сделать запрос? В начале я подключался через mysql_connect. Теперь - через new mysqli. Но некоторые говорят, что сейчас нужно подключаться через new PDO. Если честно - мне это всё не очень интересно. - Хотелось бы раз и на всегда понять, что более оптимально использовать применительно к очень недорогим хостингам? Спасибо. --- Добавлено --- Да. Совсем забыл. На входе - конечно форма. Нужно безопасно записать в базу и тут же всё прочитать. --- Добавлено --- PHP: <form> <input name="imja" value=""> <input name="familija" value=""> <input type="submit"> </form>
PHP: <? $id=$_POST['id']; $imja=$_POST['imja']; $familija=$_POST['familija']; // Нужна ли проверка на правильность ввода с точки зрения безопасности? // Я проверяю обычно просто правильность ввода $mysqli = new mysqli("localhost", "user", "password", "database"); $mysqli->query("UPDATE test SET imja='$imja', familija='$familija' where id=$id"); $r = $mysqli->query("SELECT * FROM test where id=$id")->fetch_object(); ?> <form method="post"> <input name="imja" value="<?=$r->imja?>"> <input name="familija" value="<?=$r->familija?>"> <input name="id" type="hidden" value="<?=$r->id?>"> <input type="submit"> </form>
Не то =) но с pdo это выглядело бы как то так. PHP: $dpo = new PDO('mysql:host=localhost;dbname=test', $user, $pass); $sql = "UPDATE test SET imja=?, familija=? WHERE id=?"; $stmt = $dpo->prepare($sql); $stmt->execute([$imja, $familija, $id]); $sth= $pdo->prepare('SELECT * FROM test where id= ?'); $sth->execute([$id]); $r = $sth->fetch(PDO::FETCH_OBJ); и да, я только учусь, ждус правильного ответа =)
Не интересны мне различные методы доступа к различным базам данных. Мне интересно - единственный, правильный, пацанский метод общения с базой данных на дешёвых хостингах. Вы правда не понимаете? --- Добавлено --- То есть по строкам - больше - хуже. По наглядности - хуже. По безопасности?
Вот по безопасности ,коротко и ясно =) http://phpfaq.ru/safemysql --- Добавлено --- А если есть время читать , то тут разжевано, но я сам не дочитал =) http://phpfaq.ru/pdo --- Добавлено --- Ну и чтоб подвести итог, существует только ваш личный придуманный пацанский метод (это я про класс). Все остальное это чужой непонятный код =)
@miltorg, если только с MySQL работаешь, то можно mysqli. PDO тоже не плохо, немного поопрятнее подготовленные параметры. Говорят, у mysqli какие-то преимущества по скорости, поскольку он написан только для одной СУБД, а PDO может работать с несколькими. Соответственно, универсальный код медленнее. Но не настолько, чтоб было заметно невооруженным глазом. Короче, однозначного ответа нету. Функции mysql_* устарели и удалены из современных версий PHP. Пихать в запросы сырые данные, как ты делаешь, нельзя. Либо экранирование, либо подготовленные запросы --- Добавлено --- Такого нету вообще. --- Добавлено --- Лично я предпочитаю что-то из фреймворков. КОгда проект слишком просто для тяжёлего фреймворка, использую https://github.com/auraphp/Aura.SqlQuery вместе с PDO, поскольку писать запросы руками мне не удобно (хоть я и могу при надобности), я люблю построитель запросов, поскольку они супергибкие, в них уже заложена возня с экранированием/подготовкой, и ещё много преимуществ.
Не понятно - где я это делаю - но суть не в этом. Вот тут: Пишут что PDO защищает на 100% Я очень удивился и собственно по этому сюда и написал
Как? Ну например как бы сделал я с примером выше: PHP: // Нужна ли проверка на правильность ввода с точки зрения безопасности? // Я проверяю обычно просто правильность ввода if (preg_match('/\D/', $id)) $id=103; if (preg_match('/\W/u', $imja)) $imja='Vasja'; if (preg_match('/\W/u', $familija)) $id='Pupkin';
вот тут я думал ты опытный дядя я вот этим классом пользуюсь. вот так будет выглядеть: PHP: $db = new db("localhost", "user", "password", "database"); $db->query("UPDATE `test` SET `imja`='".$db->escape($imja)."', `familia`='".$db->escape($familia)."' WHERE `id`=".(int)$id); $rows = $db->query("SELECT * FROM `test` WHERE `id`=".(int)$id)->rows;
@TeslaFeo, у него опыт на качество не оч. влияет. @miltorg, уберите вывод в форму из обработчика. Его нужно делать после редиректа. При выводе нужно выполнять HTML-кодирование – тоже важный элемент защиты. Ну и плюс то, о чем в пред. посте написали. --- Добавлено --- Что касается осн. вопроса, выбирайте между двумя вариантами. mkramer написал, на что прежде всего следует обращать внимание. PDO – это универсальность в выборе БД (по большому счету нафиг не нужна), именованные параметры в подготовленных запросах (на любителя), ну и поддержка исключений.
Я не знаю, что такое PDO (я новенький в PHP), но я не думаю, что PDO волшебным образом защитит от SQL injection. Я думаю, что ув. MouseZver имел в виду, что переданные пользователем данные надо передавать в запрос через параметры вместо того, чтобы генерить запрос на лету, тогда это будет безопасно. Пусть в Вашей форме (1-е сообщение в топике) я в качестве фамилии укажу: Код (Text): ';DELETE FROM test; Ну вот такая у меня фамилия. Тогда в Вашем варианте Вы выполните запрос Код (Text): UPDATE test SET imja='$imja', familija='';DELETE FROM test; В варианте же ув.MouseZver Вы выполняете совсем другой запрос: Код (Text): UPDATE test SET imja=?, familiya=? WHERE id=? , и что бы я ни написал вместо своей фамилии, Вашу базу данных это не сломает. Т.е. дело не в том, что PDO волшебно-безопасен, а в передачи пользовательских данных в параметрах к SQL-запросу против формирования запроса на лету.
Подготовленный запрос посылается на сервер БД для готовности принятия данных. После подготовки приходит сигнал о готовности, либо ошибка. Если ок - только тогда посылаются отдельно данные с идентификатором запроса на сервер по подготовленному там алгоритму вставки в строку. Поэтому это и есть единственный, 100% способ по защите SQL инъекции первого порядка. PDO медленнее в среднем на 6% чем MySQLi. Зависит от запроса. Почему? эмуляция / исполнимость самого инструмента. Поэтому лично отдаю предпочтение обверткам. PHP: public function binding( array ...$binding ) { $count = count ( $binding[0] ); $for = ( array ) implode ( '', array_map ( function ( $arg ) { if ( !in_array ( $type = gettype ( $arg ), [ 'integer', 'double', 'string' ] ) ) { throw new Error( 'Invalid type ' . $type ); } return $type[0]; }, $binding[0] ) ); for ( $i = 0; $i < $count; $for[] = &${ 'bind_' . $i++ } ){} ( new \ReflectionMethod( 'mysqli_stmt', 'bind_param' ) ) -> invokeArgs( $this -> lerma -> statement, $for ); foreach ( $binding AS $items ) { $items = $this -> lerma -> executeHolders( $items ); extract ( $items, EXTR_PREFIX_ALL, 'bind' ); $this -> lerma -> statement -> execute(); } } --- Добавлено --- По безопасности - лишь. В остальном это хорошая жвачка для новичком. Пока не столкнуться в необходимости расширенных стилей проверки/выводимости информации с БД. --- Добавлено --- PHP: $dpo = new PDO('mysql:host=localhost;dbname=test', $user, $pass); $stmt = $dpo->prepare( 'UPDATE test SET imja=?, familija=? WHERE id=?' ); $items = [ [...], [...], [...], [...], [...] ]; foreach ( $items AS $item ) { $stmt->execute( $item ); }
По поводу быстродействия pdo. Чувак писал что подобный запрос с 50000 записей у него занял примерно 3 секунды PHP: <?php $data = array( array('name' => 'John', 'age' => '25'), array('name' => 'Wendy', 'age' => '32') ); $insertStatement = $pdo->prepare('insert into mytable (name, age) values (:name, :age)'); // start transaction $pdo->beginTransaction(); foreach($data as &$row) { $insertStatement->execute($row); } // end transaction $pdo->commit(); ?>
Плюсадин. Единственная цифра "3 секунды на 5000 строк" не дает ничего. Я могу придумать ситуацию, когда добавление одной строки полчаса займет.
3 сек для одного запроса это очень много а 50к записей не очень много --- Добавлено --- пожалуй, просто "не много")
Я всегда считал что 3 секунды это быстро, пойду жену обрадую =)) Я же не мерюсь тут ничем, просто пример показал =)
нет не выполнится. Я провожу проверку на соответствие. См: PHP: if (preg_match('/\D/', $id)) $id=103; if (preg_match('/\W/u', $imja)) $imja='Vasja'; if (preg_match('/\W/u', $familija)) $id='Pupkin';
потому что нужно пользоваться встроенными инструментами, если они есть а к твоему способу у меня куча вопросов даже при том, что я регулярки знаю очень плохо
Приведу свой полный код, а то народ или не видит или не хочет видеть PHP: <? $id=$_POST['id']; $imja=$_POST['imja']; $familija=$_POST['familija']; if (preg_match('/\D/', $id)) $id=103; if (preg_match('/\W/u', $imja)) $imja='Vasja'; if (preg_match('/\W/u', $familija)) $id='Pupkin'; $mysqli = new mysqli("localhost", "user", "password", "database"); $mysqli->query("UPDATE test SET imja='$imja', familija='$familija' where id=$id"); $r = $mysqli->query("SELECT * FROM test where id=$id")->fetch_object(); ?> <form method="post"> <input name="imja" value="<?=$r->imja?>"> <input name="familija" value="<?=$r->familija?>"> <input name="id" type="hidden" value="<?=$r->id?>"> <input type="submit"> </form> Сломайте. Попробуйте. + есть проверка соответствия, а не простое экранирование. --- Добавлено --- Сломайте. Попробуйте. Я буду очень признателен за обучение. А пока - это просто слова