За последние 24 часа нас посетили 17504 программиста и 1281 робот. Сейчас ищут 1454 программиста ...

Как быстро освоить PHP

Тема в разделе "PHP для новичков", создана пользователем fenix_63, 16 мар 2015.

  1. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
    точно, я этот момент совсем не учитывал,
    не понимаю этих сленгов виду отсутствия опыта
    в моем случае "_" доступен, можно еще добавить "@" и "-", "!" htmlspecialchars() является правильной экранизацией или стоит еще добавить
    mysql_escape_string()
     
  2. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    А эти данные откуда взялись? От клиента. А клиенту какой уровень доверия должен быть? Нулевой. Клиент - твой враг. Всегда надо исходить из этого. PHP умеет проверять mimetype файла своими средствами, на сервере. Почитай и про другие функции для работы с файловой системой. По-хорошему, нужно проверять на сервере mime, сравнивать его с mime, пришедшим от клиента, сопоставлять их с расширением файла. Все это должно совпадать. Для картинок есть еще один хак - пересохранить ее через какой-нибудь инструмент картинку так, как надо тебе. Если это реальная картинка, с ней все будет ок. Если файл левый, то упс. Либо, без пересохранения, просто попробовать открыть файл как картинку.
    Копипаста - это от copy-paste. Копирование вставка. То бишь, я скопировал некий текст, и вставил его в инпуты пароля. По какой-то причине к ошибке, связанной с запрещенными символами, прибавилась ошибка несовпадения, хотя она исключена.
    Ды вообще все должно быть доступно. Включая кириллицу и апострофы. Пусть пользователь хоть валидный mysql или js фигачит себе в логин. Это его дело. Если ты все правильно сделаешь, у тебя ничего не сломается при этом.
    htmlspecialchars() ничего не экранирует. И использовать ее следует только при выводе информации, а не при записи в базу. Она будет гарантировать, что всякие там угловые скобочки в тексте не сломают тебе верстку на странице. А это важно. Это не вопрос безопасности, это вопрос именно вот взаимодействия твоего контента и браузера.

    mysql_escape_string() - это вот да, для экранирования при записи. НО. Сегодня расширение mysql_ не актуально. Оно устарело и умерло. Натурально. Его выпилили из PHP. Сейчас надо использовать mysqli_ и экранировать через mysqli_real_escape_string();
     
    Aleksanbr_77 нравится это.
  3. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
  4. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    Что-то я не въехал, зачем в сессию писать номер сессии... Ну да ладно. Разбиение на модули, а не один бесконечный файл, радует. Отсутствие экранизации не радует. https://github.com/77Alleksandr77/77Alleksandr77/blob/master/lib/funkc.php#L14 - зачем столько усилий? IP посетителя (точнее, последний IP в цепочке проксей) должен быть в $_SERVER["REMOTE_ADDR"]. Если он где-то ещё, то нужно ругаться с хостером или перенастраивать свой сервер (если это доступно).

    Все SQL-запросы без экранизации. Поэтому мало того, что данные могут поломать их (я в коммент введу апостроф, и усё, хотя я ничего плохого не имел в виду) , так ещё и создаётся опасность взлома через SQL-инъекцию.

    В случае неудачных запросов глубокомысленная надпись "нет селекта из БД" пользователю ни о чём не говорит. Лучше написать: "Техническая ошибка на сайте. Она будет исправлена в ближайшее время")

    Не надо здоровые куски html выводить через echo. Для этого придумано отключение/включение режима PHP

    Ну это что пока заметил
     
    Aleksanbr_77 нравится это.
  5. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
  6. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
    это для меня, просто не переписал многие такие вещи
    сохранил файл к себе и не смотрел куда сохраняется, а затем все разом на гит и выкинул. а он в блокс сохранился,
    --- Добавлено ---
    при первом входе, когда сессия не начата, что бы вспомогательный информ блок был на виду я сделал id_session, и присвоил тру, в далнейшем id_session фолс и блок отображается в нижней части страници
    --- Добавлено ---
    уже знаю, буду исправлять, а от sql инъекции я считал что как вариант использовать метод пост, а не гет, может я и ошибался, не знаю, еще не углублялся в sql инъекции, так, бегло ознакомился
    --- Добавлено ---
    спасибо!!!
     
  7. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Поехали:

    1)
    Определись, или на инглише, или транслитом. Но не смешивай и то и то. Лучше, конечно, все сразу на инглише писать.

    2)
    О хранении пароля в сессии на форуме уже не один талмуд написан. Смысла в этом нет. Просто храни флаг, залогинен ли пользователь. Дергать на каждый чих бд и проверять данные, которые в принципе не могут измениться за время сессии - пустая трата процессорного времени.

    3)
    Такие вещи лучше заменить на switch.

    4)
    Брать $i в кавычки тут не нужно :) Оно ничего не сломает, конечно, но это лишнее.

    5)
    Ну про это ты уже знаешь все.

    6) Раз
    Два
    Какой смысл в двух местах сразу брать хэши? Лучше же в одном каком-нибудь.

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

    8) if и выполнение условия в одну строку лучше не писать. Правило хорошего тона - писать с фигурными скобками и переносом строк. Даже если исполняемая строка всего одна.

    9) Хех, паливо, что чужой код(с вероятностью 95%):
    PHP:
    1.  while (list(, $entry) = each($entries))
    2.           {
    3.              $entry = trim($entry);
    4.              if ( preg_match("/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/", $entry, $ip_list) )
    5.              {
    6.                 $private_ip = array(
    7.                       '/^0\./',
    8.                       '/^127\.0\.0\.1/',
    9.                       '/^192\.168\..*/',
    10.                       '/^172\.((1[6-9])|(2[0-9])|(3[0-1]))\..*/',
    11.                       '/^10\..*/');
    12.                 $found_ip = preg_replace($private_ip, $client_ip, $ip_list[1]);
    13.                 if ($client_ip != $found_ip)
    14.                 {
    15.                    $client_ip = $found_ip;
    16.                    break;
    17.                 }
    18.              }
    19.           }
    10) У тебя на каждый чих дергается connectDB(); в котором совсем не проверяется, было ли уже открыто соединение ранее, или нет. Это не здорово.

    11)
    PHP:
    1. while ( list( $nomer_foto, $foto_array ) = each( $array_foto ) )
    2.             {
    3.              
    4.                 while ( list( $varname, $ssilka )= each ($foto_array) )
    5.                 {
    6.                     if ($varname=='file')
    7.                     {
    8.                         $array_ssilka["$i"]=$ssilka;
    9.                         $i++;
    10.                     }
    11.                 }
    12.             }
    Окей, ладно в вышеприведенном коде была сожная конструкция с деструктуризацией итераторов, но зачем ее дальше использовать? :) Или предыдущий код был не позаимствованный, и ты везде так пишешь? Кто тебя этому учил? Есть же foreach($array as $key=>$val). Честно, впервые вижу такую организацию обхода массива.

    12)
    PHP:
    1. <?php
    2.     if(session_id() == '')
    3.     //$session_id = session_id()  
    4.     {
    5.         session_start();
    6.         if ( !$_SESSION['session_id'] )
    7.         {
    8.             $_SESSION['session_id'] = session_id();
    9.             $session_id = false;
    10.             //echo session_id()."<br>";
    11.             require_once "lib/funkc.php";
    12.             require_once "html/html_bodi.php";
    13.             user_vizit($_SESSION["user_name"]);
    14.         }
    15.         else
    16.         {
    17.             $session_id = true;
    18.             require_once "lib/funkc.php";
    19.             require_once "html/html_bodi.php";
    20.         }
    21.     }
    22.     else
    23.     {
    24.         $session_id = true;
    25.         require_once "lib/funkc.php";
    26.         require_once "html/html_bodi.php";
    27.     }
    28.      
    29.      
    30. ?>
    Независимо от происходящего у тебя коннектится "lib/funkc.php"; может, стоит вообще вынести ее "за скобки"?

    13) https://github.com/77Alleksandr77/77Alleksandr77/blob/master/reg.php - есть ли смысл инклудить файл, который не делает ничего, кроме приинклуживания другого файла?

    На этом, вроде, все.
     
    Aleksanbr_77 нравится это.
  8. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
    да, каюсь, нашел в нете,
    для себя, разные способы применяю с целью тренировки
    --- Добавлено ---
    точно!!!
    --- Добавлено ---
    даже не думал над таким вариантом, а вариант в самом деле классный, спасибо!
    --- Добавлено ---
    Код (Text):
    1. if ( $i==3 ) {echo "$row"; }
    тоже можно без кавычек, обычно так и пишу, сейчас пропустил чёто,
    --- Добавлено ---
    Код (Text):
    1. if (url()=='reg.php') $title = 'Регистрация';
    ради этих проверок, все кроме регистрации проходит на индекс.пхп
    --- Добавлено ---
    а нет, иначе не будет срабатывать строка
    Код (Text):
    1. user_vizit($_SESSION["user_name"]);
    --- Добавлено ---
    только ради нее
     
  9. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
    C праздником всех!
    Самые грубые ошибки исправил, на гатхабе файлы также отредактировал! Но есть один момент,
    Пользователь может в любой момент закрыть страницу, не прерывая сессии и БД останется открытой, или в этом нет ничего страшного и close() срабатывает автоматом при закрытии страници или окна браузера?
     
  10. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    http://phpfaq.ru/na_tanke
    Когда пользователь что-то видит в браузере, соединение с БД уже давно закрыто
     
  11. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
    @mkramer
    как же тогда не дергать connectDB() каждый раз? Со всем остальным разобрался а с этим вопросом нет.
     
  12. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Дерни один раз в точке входа и сохрани коннект.
    Да, это будет "каждый раз при вызове скрипта". Но у тебя-то сейчас коннект дергается вообще в каждой функции при каждом обращении к БД.
     
    denis01 и Aleksanbr_77 нравится это.
  13. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
    @Fell-x27 А могу ли я попросить ссылку на ресурс по этой теме, то что я читаю-везде в примерах
    PHP:
    1. <?php
    2.  
    3. /* Подключение к серверу MySQL */
    4. $mysqli = new mysqli('localhost', 'user', 'password', 'world');
    5.  
    6.    printf("Подключение к серверу MySQL невозможно. Код ошибки: %s\n", mysqli_connect_error());
    7.    exit;
    8. }
    9.  
    10. /* Посылаем запрос серверу */
    11. if ($result = $mysqli->query('SELECT Name, Population FROM City ORDER BY Population DESC LIMIT 5')) {
    12.  
    13.     print("Очень крупные города:\n");
    14.  
    15.     /* Выбираем результаты запроса: */
    16.     while( $row = $result->fetch_assoc() ){
    17.         printf("%s (%s)\n", $row['Name'], $row['Population']);
    18.     }
    19.  
    20.     /* Освобождаем память */
    21.     $result->close();
    22. }
    23.  
    24. /* Закрываем соединение */
    25. $mysqli->close();
    26. ?>
    пытался вернуть результат своей функции $link = connektDB() и затем передавал его All_foto($link)
    PHP:
    1. $success=$mysqli->query( $link, "INSERT INTO  `$table`(`login` ,`pass` ,`data`, `ip`)
    2.        VALUES ('".$reg_name_escape."','".$reg_pass."','".$data."','".$ip."')");
    но положительного результата не добился.
    --- Добавлено ---
    или я не правильно представляю себе "алгоритм" действий:
    -сохранить в переменную результат выполнения connectDB();
    -в дальнейшем передавать его в функцию, которая использует подключение к БД
     
  14. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
    разобрался! $link -ТОЛЬКО для процедурного стиля:eek::confused:
     
  15. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    что тебя смущает?
     
  16. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
  17. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
    #467 Aleksanbr_77, 13 май 2017
    Последнее редактирование: 13 май 2017
  18. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    Почему везде поиск идёт по имени пользователя, а не по ID? По ID же быстрее.

    https://github.com/77Alleksandr77/task/blob/master/funkc.php#L57 - вместо этих двух строк просто
    PHP:
    1. return $count["count"];
    Для работы с датами много велосипедов. Твой велосипед не отсеивает 29 февраля в невисокосных годах, стандартные фунциии - отсеивают. Держи: https://secure.php.net/checkdate, https://secure.php.net/manual/ru/function.date-diff.php

    Ну и раз у тебя всё и так вводится отдельно, сделай селекты хотя бы для числа и месяца :) А можно и для года

    Обработчики форм не редиректят - это плохо. Почитай этот тред. Каждый обработчик форм методом POST должен редиректить куда-нибудь, а не выводить сам что-то в браузер. Тогда не будет проблемы с двойной отправкой и с выскакиванием дурацких окошек при попытке обновить страницу.

    Данные для запросов вроде эскейпишь, das ist gut, однако попробуй ещё поиграться с подготовленными запросами
     
    #468 mkramer, 13 май 2017
    Последнее редактирование: 13 май 2017
    Aleksanbr_77 нравится это.
  19. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
    @mkramer а я "пыхтел", писал этот "велосипед", а есть готовые, подставляй и пользуйся, думал еще проверку делать на февраль месяц, но в ТЗ на этот счёт нечего не сказано, я и не делал! а тут просто- отдай в функцию и получи готовый результат!
    А на счет редидекта, в ТЗ: может я его не так понял.
     
    #469 Aleksanbr_77, 13 май 2017
    Последнее редактирование: 13 май 2017
  20. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Ты не представляешь сколько есть подобных вещей во всех языках, включая пхп. По этому берем за правило - сначала гуглим и читаем доку, потом пишем что-то. А лучше залпом глазами пробежаться по документации, работа со строками, с массивами, с файлами, с бд, это вот все, чтобы в памяти что-то да отложилось, чтобы потом знать, где искать нужную функциональность.
     
  21. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    Редирект после поста - это само собой разумеющееся, его не пишут в ТЗ, оно подразумевается. Так же как в ТЗ не пишут: "ескейпить данные перед вставкой в SQL запросы" - это тоже само собой. После успешного логина, после прибавления единицы, после чего угодно, что пришло на сервер постом - должен быть редирект куда-нибудь. Даже на ту же самую страничку.
     
  22. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
    Мне когда то попался материал, в котором говорилось как написать запрос что бы при обращении к заданному полю его значение увеличивается на 1 и не надо :
    получил значение переменной;
    изменил значение переменной;
    записал значение переменной;
    сейчас не могу найти
     
  23. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    Для этого нужен целый материал? Почитай про UPDATE
     
    Aleksanbr_77 нравится это.
  24. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    upload_2017-5-13_16-51-43.png
    Есть в этом что-то эдакое, какая-то своя глубинная идея, что поймут не только лишь все...

    Поехалей:
    1) Окошки ввода для даты хорошая идея только при условии, что ты хотя бы формат ввода укажешь. Но и это уже лишняя нагрузка на мозг пользователя. Как было сказано ранее - юзай выпадающие списки. Я это говорил тысячу раз, и скажу снова - их юзают все. Даже гиганты Интернета. Потому что это проверено, это работает. Более того, это даже удобнее и быстрее чем эти вот виджеты с календариками, я гарантирую это.

    2) Придирка конечно, но, окошко таки не по центру:
    upload_2017-5-13_17-0-46.png

    Почитай про flexbox на досуге, гарантирую, тебе понравится. Забудешь на век про эти вот "ой, тут чуть шире стало, надо везде отступы пересчитать, а то все поехало".

    3)
    В коде, отвечающем за выход:
    PHP:
    1. unset( $_POST['check_enter'], $_POST['check'], $_SESSION['user_name'], $_POST['exit']);
    2.         require 'index.php';
    Гляди, в случае, если ты не хочешь, чтобы дальше шла логика приложения, и чтобы она не обрабатывала дальше содержимое POST, которое, по-хорошему, будет отсутствовать, но может и присутствовать, потому что злоумышленник-бяка, достаточно просто схлопнуть сессию и сделать exit или die.

    Если ты хочешь почистить POST, ты можешь просто сделать $_POST = []. Но это не самая хорошая практика. Трогать эти суперглобалы крайне нежелательно.

    4) Ты езде юзаешь только Include и require без _once. Надо осторожнее с этим быть. Потенциально множественные инклуды и реквайры желательно использовать только тогда, когда это заложено в архитектуре и необходимо в логике. В противном случае это может выйти боком. Либо начнутся дикие костыли как у адептов ненависти к буферам вывода, которые свои приложения готовы в узел завязать, лишь бы заголовки выводились только до контента. В итоге сковывают себя по рукам и ногам и радуются этому. Жалкое зрелище. По возможности избегай этого и позволь PHP решать эти проблемы за тебя, чтобы не париться.

    5)
    PHP:
    1. $mysqli->query( "SET NAMES 'UTF8'");
    Гляди, для таких вещей не надо больше юзать запросы. Служебные запросы в PHP умерли вместе с расширением mysql_. Давай чисто логически подумаем, что ты тут делаешь? Ты отсылаешь запрос, чтобы указать БД, в какой кодировкедолжны обрабатываться запросы :)
    Это само по себе анекдот. И одна из причин, почему от mysql_ отказались.

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

    6) https://github.com/77Alleksandr77/task/blob/master/for_entrance.php - файл phpшный, но в нем нет ни строки php :) Ну так и сохранял бы его в html. Да, Html-файлы тоже можно инклудить. Никаких проблем нет. Любые текстовые файлы можно инклудить, что уж там. Если там будет php-код, он будет выполнен. Если будет что-то окромя php, оно просто пойдет как текст. Технически, конечно, тут никакой ошибки у тебя нет, но по семантике html-файлик пусть будет html-файликом. Чисто вот мое мнение.

    7) Чистить каждый раз POST, как ты делаешь, не обязательно. Он и так при каждом запросе новый будет.

    8)
    PHP:
    1. if ( !$_POST['user_password'] )
    2.     {
    3.         $error_enerance[] = "Пароль не введён";
    4.         unset ( $_POST['user_password'] );
    5.     }
    "Если переменная не существует, уничтожь эту переменную".

    9) В entrance.php и check_enter.php много дублирующегося кода. Зачем? :)

    10) И в целом немного странная архитектура. Вроде код порезан на файлы. Но в этих файлах потоковые скрипты. При этом есть и чуть чуть функций, но только в одном месте. Нет единой идеи, чтоли. Тут уж либо так, либо так., как по мне. Но это все со временем придет так или иначе.

    Вроде все.
     
    Aleksanbr_77 нравится это.
  25. Aleksanbr_77

    Aleksanbr_77 Новичок

    С нами с:
    31 янв 2016
    Сообщения:
    115
    Симпатии:
    5
    по энерции сделал рнр -шным, когда-то я даже в ini файлы записывал рнр код, и инклюдил их, но и вы мне сказали что это плохая техника, да согласен,
    тогда при обращении к файлу напрямую вылазит просто код записанный в файле, но тут в самом деле можно было его сделать нтмl.
    да, так, ради :D, в первом варианте ссылка была подписана "НАЗАД",
    в предыдущем задании все делал только с _once тут так...
    PHP:
    1. $mysqli->query( "SET NAMES 'UTF8'");
    пробовал и без нее, работает! но во всех примерах в мануалах присутствует, решил - значит так надо,
    я вообще к этим мануалам неравнодушен иногда, недавно читаю про функцию, пишут; что она принимает только 2 параметра, я решил проверить и всунул ей 4 и ничего, сработала, а вот 3- мало! а 2 в самый рас!