Автор Тема: Prepared Statement  (Прочетена 1131 пъти)

0 Потребители и 1 Гост преглежда(т) тази тема.

theSit

  • Full Member
  • ***
  • Благодарности
  • -Казани: 18
  • -Получени: 3
  • Публикации: 152
Prepared Statement
« -: 26 Септември 2014, 14:16:55 »
Здравейте. Нов съм в php и mysql и като цяло в програмирането, намирам форума за полезен и идвам със следният въпрос.
Достатъчно сигурен ли е кода, който съм написал по-долу:

Код: PHP
  1. <?php
  2.  
  3. if(isset($_POST['submit'])){
  4.  
  5. $uname = $_POST['username'];
  6. $pword = $_POST['password'];
  7.  
  8. /*** mysql hostname ***/
  9. $hostname = 'localhost';
  10.  
  11. /*** mysql username ***/
  12. $username = 'root';
  13.  
  14. /*** mysql password ***/
  15. $password = 'password';
  16.  
  17. try {
  18.     $link = new PDO("mysql:host=$hostname;dbname=testing", $username, $password);
  19.  
  20.     echo 'Connected to database<br />';
  21.  
  22.     $stmt = $link->prepare("INSERT INTO gamb_e  VALUES (?, ?)");
  23.        
  24.         try{
  25.         $stmt->execute(array("$uname", "$pword"));
  26.         } catch(PDOException $e){
  27.        
  28.                 echo "Exception caught: $e";
  29.        
  30.         }
  31.  
  32.     /*** echo the number of affected rows ***/
  33.     //echo $count;
  34.  
  35.     /*** close the database connection ***/
  36.     $link = null;
  37.     }
  38. catch(PDOException $e)
  39.     {
  40.     echo $e->getMessage();
  41.     }
  42.  
  43. }
  44. ?>
  45.  
  46. <html>
  47.  
  48. <form action='index.php' method='post'>
  49.  
  50. <input type="text" name="username" >
  51. <input type="password" name="password" >
  52. <input type="submit" name="submit" value="submit">
  53.  
  54. </form>
  55.  
  56. </html>
  57.  
  58.  

Добра ли е идеята да се ползва prepared statement и pdo?
« Последна редакция: 26 Септември 2014, 14:27:34 от theSit »

HanKrum

  • Hero Member
  • *****
  • Благодарности
  • -Казани: 120
  • -Получени: 73
  • Публикации: 991
  • Кибик
Re: Prepared Statement
« Отговор #1 -: 26 Септември 2014, 18:52:04 »
Здравей и добре дошъл. Нямам време да погледна кода, но на пръв поглед забелязах пароли. Ако файла се намира вън от уеб сървъра, може да се каже, че има някаква сигурност.
...
Добра ли е идеята да се ползва prepared statement и pdo?
... даже е препоръчително :)

п.п. Не смесвай php и html
"Силата на правителството се крепи на невежеството на народа, и те знаят това и винаги ще се борят против просвещението." Лев Толстой

jazzman

  • Hero Member
  • *****
  • Благодарности
  • -Казани: 25
  • -Получени: 190
  • Публикации: 3623
Re: Prepared Statement
« Отговор #2 -: 26 Септември 2014, 19:46:07 »
@theSit, welcome a board ;)

Тва дет си го написал не е prepared statement. Набора те е метнал нещо. Много неща могат да се кажат по-кода стига да искаш да учиш :)
Java is to Javascript as fun is to funeral.

http://nau4i.me/forum/index.php/topic,15129.0.html

HanKrum

  • Hero Member
  • *****
  • Благодарности
  • -Казани: 120
  • -Получени: 73
  • Публикации: 991
  • Кибик
Re: Prepared Statement
« Отговор #3 -: 26 Септември 2014, 19:51:21 »
... Нямам време да погледна кода, но ...
Наборе чети бе ;)
"Силата на правителството се крепи на невежеството на народа, и те знаят това и винаги ще се борят против просвещението." Лев Толстой

theSit

  • Full Member
  • ***
  • Благодарности
  • -Казани: 18
  • -Получени: 3
  • Публикации: 152
Re: Prepared Statement
« Отговор #4 -: 26 Септември 2014, 20:18:35 »
Цитат
Тва дет си го написал не е prepared statement.

Ами гледах уроци на Гатака, също така и други подобни и там казаха, че php прави prepared statement по този начин  ???

jazzman

  • Hero Member
  • *****
  • Благодарности
  • -Казани: 25
  • -Получени: 190
  • Публикации: 3623
Re: Prepared Statement
« Отговор #5 -: 26 Септември 2014, 21:33:38 »
Най-вероятно са го спестили ( което е голяма грешка ) или не са знаели ( човешко е ), че по дифоулт pdo библиотеката ( не знам за mysqli ) не преперва нещата по начина по който трябва да бъдат. Вместо това дивелопърите на php по някаква незнайна за мен причина въвеждат нещо като емулация на prepared stаtement, чието действие се извършва във транспортният слой на драйвъра, а не в самата база данни, където му е мястото :) Кода не е зле, но имам някои забележки и препоръки. Ако имам време по късно ще се опитам да отговоря по детайлно.

Слято мнение: 27 Септември 2014, 01:17:34
Ще се опитам да дам отговор и някои препоръки в/у кода ти. 

1. Опитай се да не смесваш html / javascript  / css с php в един документ. За по-добър дизайн ползвай някоя готова функция за инклудване, като include(), require() и т.н. Има готови темплейтни системи, като смарти, туиг и други които са създадени точно с тази цел, да разделят бизнес логиката, сиреч кода който се изпълнява в/у сървъра от презентацията с други думи генерираният код в/у браузъра ти. Ползването на такива системи обаче изискват добри познания в езика, но само я споменавам като опция в бъдещето.

2. Ползваш root като оторизиран / регулярен потребител, за извличане / инсъртване на някаква дейта. Недей! Никога не ползвай root, тук или където и да е било в апликейшъна. Идеята да се влиза като руут е само една. Оправяне на някаква каша, задаване на права или в ситуации на тежък бъг нуждаещ се от сериозен дебъгинг.

3. Паролата на потребителя за връзка с базата не трябва да е предвидима. Повече символи и по дълга парола винаги е по добре. Виждам, че разработваш локално, но го споневам да се знае.   

4. Когато ползваш insert sql statement, винаги листвай колоните в/у които инсъртваш стойностите. Това ще ти даде добра описателност в/у колоните, по-добра подръжка или правене на случайни грешки и не на последно място по добра производителност. Понеже си-кю-ел парсъра чете стринга алогично за нас - отзад- напред.
Код: SQL
  1. // лошо
  2. INSERT INTO TABLE VALUES(1,2,3,4)
  3. // добo
  4. INSERT INTO TABLE(col_1,col_2,col_3,col_4) VALUES (1,2,3,4)
  5.  

5. Ползването на prepared statement не е част от апликейшън езика, сиреч - perl, php, bash, python и т.н.. Много програмисти мислят, че за този процес се грижи php или там езика на който пишат. НЕ Това е процес, който се изпълнява в базата данни. Няма да се спирам на детайли, но това, което трябва да знеш е, че след като темплейта ( sql template ) бива изпратен от pdo драйвъра към базата, парсъра на базата данни го взема, компилира го, прави го във байнъри executable формат мисля че се нарича BLR (Binary Language Representation) на тва нещо му се прави чек на много ниско ниво се изпраща на екзеция :) Можеш да имаш много prepared statement, но execute statement-a  един. Тва е едно от силните му черти и зависи изцяло как базата е проектирана.Това истинският prepared statement.  Всичко друго е ала-бала портокала, ще дам пример по долу. 

6. Добре си се насочил към PDO.Eдна от най-сиlните mu черти e възможноста да се свързва към различни бази ползвайки един и същ синтакс. Също така го намирам за много по изчистен от mysqli_ driver-a. Eто пример към firebird:

Код: SQL
  1. $usr = 'SYSDBA';
  2.  
  3. $pass = 'masterdba';
  4.  
  5. $dbh = NEW PDO("firebird:host=::1;dbname=/var/firebirddata/new.fdb;charset=utf8", $usr, $pass,
  6.         array(
  7.         PDO::ATTR_EMULATE_PREPARES => FALSE,
  8.         PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  9.         PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_NUM,
  10. ));
  11.  
  12. $sql = "SELECT p.CODE, p.NAME, p.PASS FROM FETCH_DATA  p;";
  13.  
  14. $stmt = $dbh->PREPARE($sql);
  15.  
  16. $stmt->EXECUTE();
  17.  
 

Note: За да се случи действителен prepared statement ти трябва да сетнеш ATTR_EMULATE_PREPARES => false. Виж в примера.

Давам ти още един пример в mysql, за да видиш, кво се случва в действителност в базата, при  ATTR_EMULATE_PREPARES =  true и false:
Код: PHP
  1. <?php
  2.  
  3. ini_set('display_startup_errors',1);
  4.  
  5. ini_set('display_errors',1);
  6.  
  7.  
  8. $database_options = array(
  9. PDO::ATTR_EMULATE_PREPARES => false
  10. , PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
  11. , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
  12. );
  13.  
  14. $database = new PDO('mysql:host=lxc.centos.local;dbname=test;charset=utf8', 'lxc', 'password', $database_options);
  15.  
  16. show_prepared_statements();
  17.  
  18. // *One* prepared statement
  19. $stmt = $database->prepare('SELECT 1 + 1 FROM DUAL');
  20.  
  21. // ... getting executed 10 times
  22. for($i = 0; $i < 10; $i++){
  23. $stmt->execute();
  24. }
  25.  
  26. $rs1 = $stmt->fetch();
  27.  
  28. //$stmt->closeCursor();
  29.  
  30. echo '<br>';
  31.  
  32. show_prepared_statements();
  33.  
  34. echo "<br>";
  35.  
  36. echo '<pre>' . print_r($rs1, true) . '</pre>';
  37.  
  38. function show_prepared_statements() {
  39.  
  40. global $database;
  41.  
  42. $statements = $database->query("SHOW SESSION STATUS LIKE 'Com_stmt_%'");
  43.  
  44.  foreach ($statements as $statement) {
  45. echo $statement['Variable_name'] . ': ' . $statement['Value'] . '<br>';
  46.    }
  47. }
  48.  
  49.  
  50.  

Много неща още бих могъл да напиша, но мисля, че тва е достатъчно за начало. И един съвет от мен - винаги тествай, няма значени кой го е казал и с какъв ранг в твоите очи :)  Тва се отнася и за написаното от мен. Сам трябва да откриеш кои са добрите практики и кое е най-доброто за теб.

Слято мнение: 27 Септември 2014, 01:19:48
И кво и при дълъг постинг ли ще се слива мнението ми.... Ебати и простотията  :o ......а то не било към същият пост а към този отпреди 5 часа.....което е още по-голяма простотия....поне намалете тайминга на 1 час да речем
« Последна редакция: 27 Септември 2014, 01:29:48 от jazzman »
Java is to Javascript as fun is to funeral.

http://nau4i.me/forum/index.php/topic,15129.0.html

theSit

  • Full Member
  • ***
  • Благодарности
  • -Казани: 18
  • -Получени: 3
  • Публикации: 152
Re: Prepared Statement
« Отговор #6 -: 27 Септември 2014, 11:44:33 »
Lol...благодаря ви за този отговор и за отделеното време  :)