Здравствуйте. Хочу вкатиться в Веб-программинг с нуля. Владею только ANSI C в объеме практических приложений. С чего начать? Скачал книжку "Адам Трахтенберг, Дэвид Скляр - PHP. Рецепты программирования, 3-е издание - 2015" "PHP 5 полное руководство" Программу PHP Designer 7.2.5. Это то, что мне надо?
Плохой совет, книги всегда выигрывают перед упрощённым курсом. Рецепты - это для тех, кто уже знает PHP. Лучше тоже Скляра, но вот эту: https://www.ozon.ru/context/detail/id/139127353/ После C будет тяжело привыкнуть к тому, что всё нетипизированно в PHP, но, поскольку синтаксис почти тот же самый, можно освоить за неделю (я сам после C осваивал, через две недели сделал первый заказ за "спасибо", через месяц - за деньги)
Благодарю за ответы. Краткий курс изучаю, но замечаю некоторые неточности, после С это вызывает у меня недоверие то ли к автору курса, то ли к языку, то ли к технологии. Например, копирую пример в редактор, создаю html, открываю в браузере - и вижу кракозяблы. Оказывается, редактор должен поддерживать UTF-8, но про это не сказано. А случайно CodeBlocks не поддерживает PHP? И еще, существует ли полный актуальный справочник по тегам? потому что обучение строится на примерах, а мне, как творцу, хотелось бы иметь под рукой полный инструментарий. У меня где-то валялась книжка по HTML3, но она безнадежно устарела, да и я не знаю, где она сейчас.
@Rexfan, не надо краткий курс, это для полных чайников, а вы же профи в C Вы же C не по краткому курсу изучали? Я вам книгу дал, где язык разобран с азов до проф. фреймворков. По тегам всегда пользовал, и до сих пор пользую htmlbook.ru. Вроде, у них есть обновлённая версия на другом домене, но я не помню. Плюс вам ещё нужен будет JavaScript обязательно, он тоже C-подобный, но есть несколько вещей, которые сводят в нём с ума До сих пор, хотя он у меня практически основным инструментом на работе сейчас стал. https://learn.javascript.ru - на мой взгляд, прекрасная штука. --- Добавлено --- По поводу кодировок - там всё сложнее, тут же у нас ещё одна переменная в игре - веб-сервер. Поэтому правило такое: исходники utf-8, в html <meta charset='utf-8'>, в заголовке ответа utf-8 (можно передать из php или настроить веб-сервер на отдачу заголовка), соединение с базой utf-8. Основные IDE для PHP это PHPStorm, Zend Studio (платные), NetBeans (бесплатный). Вроде Visual Code от мелкомягких тоже умеет, но я пока не научился настраивать.
@mkramer, спасибки, ушел изучать... Оказывается, у меня уже довольно много опыта в разных вещах, чтобы отличать хреновенький учебник от хорошего
Такой вопрос подхода. Как известно во фреймворках на основе MVC для доступа к базе используются модели. Ночто-то как-то у меня с ними не срослось. Я делаю следующим образом. Например из формы через роут прилетают данные в контролер, в котором осуществлем следующий финт ушами Код (Text): public function login(Request $request) { validate($request,["login"=>require|unique|aplpha|numeric, "pass"=>require]); //не суть важно - вобщем необходимые проверки полей с помощью валидатора $getAcces = new Login; $login= $getAcces->login($request->login, $request->pass); ... } А уже в самом классе Login обращаюсь к базе либо через "сырой запрос" фасада DB, либо используя функции фреймворка - в данном случае Ларавеля. Таким образом я имею возможность вернуть из Login->login любое значение которое мне нужно(я его могу запрограммировать) для приложения (обычно это массив из флага авторизация да/нет, юзернейма(хотя это не обязательно имя - устанавливается в сессии), каких то других аттрибутов - например для разделения прав пользователей). Плюс, при таком подходе я могу всю большую логику раскидать по методам классов, и сам контроллер получается худым - все как завещали создатели MVC Так вот насколько можно или нельзя использовать такой подход? И если нельзя, то собственно в чем криминал такого подхода? Просто убей не пойму, зачем придумали модели, если я могу написать свой класс в котором сосредоточить все необходимые приложению запросы в БД. Сейчас модели не юзаю вообще.
@Bastonc, ваш класс - тоже модель, по сути. Если вы имеете в виду под моделями реализацию ActiveRecord (Eloquent, к примеру), то это просто удобно, когда большую часть запросов за тебя делает сам фреймворк, плюс отвечает за связи и т.п. Особенно для мелких приложений. Хотя, в крупном может создать проблемы. Тогда там используется DataMappper обычно. Твой подход тоже имеет право на существование, так делали в CodeIgniter, к примеру. Лично мне не нравится, но это ИМХО.
В модели реализуется осн. логика. Естественно, если это обработка данных в том числе и из БД, данные нужно получить из БД. Как выше написали, по сути это и есть типичная работа с моделью из контроллера: PHP: $getAcces = new Login; $login= $getAcces->login($request->login, $request->pass);
Код (Text): <?php echo "<strong>$_POST array:</strong><br>"; print_r($_POST); echo "<br><br><br>"; if (!empty($_POST)){ $message = "Новая регистрация сервера: \n" . "Название сервера:" . $_POST['server_name'] . "\n" . "Дата открытия:" . $_POST['server_date'] . "\n" . "Рейты сервера:" . $_POST['server_rate'] . "\n" . "Хроники сервера:" . $_POST['select_m'] . "\n" . "Url сервера: " . $_POST['url_adr']; $resultMail = mail("моя почта, "Регистрация сервера", $message ); if( $resultMail ) { echo "Сообщение отправленно!!"; } else { echo "Что то пошло не так!!!"; } } ?> ------------------------------------------------------------ $(document).ready(function() { $("#form").submit(function() { $.ajax({ type:"POST", url: "../libs/submit.php", data: $(this).serialize() }).done(function() { $('#contact_form').html("<div id='message'></div>"); $('#message').html("<h2>Регистрация прошла успешно.</h2>") .append("<p>Ваш сервер пройдет модерацию и вскоре будет добавлен.</p><br><p>Удачерного дня!</p>") .hide() .fadeIn(1600, function() { }); }); return false; }); }); вместо большого нолика)) блок с формой закрывается полностью)) #message { display: -webkit-flex; display: -moz-flex; display: -ms-flex; display: -o-flex; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-flex-direction: column; -moz-flex-direction: column; -ms-flex-direction: column; -o-flex-direction: column; -webkit-box-orient: vertical; -webkit-box-direction: normal; flex-direction: column; -ms-align-items: center; -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center; width: 100%; height: 100%; padding: 10px; -webkit-border-radius: 30px; -moz-border-radius: 30px; border-radius: 30px; -webkit-box-shadow: 0 0 10px #000; box-shadow: 0 0 10px #000; background-color: #131519; } вот так)) форму я сам написал (после удаление скопипастенной) а вот ajax где то надыбал глубокой ночью)) я просто не знал что так можно)) я на любительской ступеньке сайтостроения)) в общем html, css, js и php с бд начал изучать с 17 числа того месяца или около того)) всё работает и на почту отсылает....но вот меня не покидает ощущение что я допустил ошибку в php она как бы не даёт о себе знать сейчас но, когда-то аукнется) можете подсказать что я сделал не так?) php меня волнует)) с jquery всё нормально мне нравится результат) да и форму закрывает, по моей наивности я думаю это лишняя защита))))) печатая этот пост мне кажется я забыл защитить форму от инъекций)) я еще не знаю что это но вчера где то прочитал что такое есть)) --- Добавлено --- https://html5book.ru/ кажется вот их обновлённая версия) Моё мнение дилетанта что если углубиться в css ничуть не легче чем php, а php для человека изучающего его без году неделя весьмя труден)) как я понял css идет в очень сильной связке с js и библиотеками
Ну в вебе всё связано: php или другой серверный язык для логики сервера, js и его производные (TypeScript. CoffeeScript и прочее) для работы на клиенте, css для вёрстки.
Вроде все сделал как описано в ТЗ. Буду очень раз здравой критике, пожеланиям и советам. index.php PHP: <?php require('db.php'); $data = $_POST; if(isset($data['do_login'])){ $errors = array(); $user = R::findOne('users', "login = ?", array(trim($data['login']))); if($user){ if(password_verify($data['password'], $user->password)){ $_SESSION['logged_user'] = $user; header('Location: /'); }else{ $errors[] = 'Пароль неверный'; } }else{ $errors[] = 'Логин указан неверно'; } if(!empty($errors)){ $result = '<div class="result result_door" >'.array_shift($errors).'</div>'; } } if(isset($data['do_counter'])){ $id = $_SESSION['logged_user'] -> id; $counter = $_SESSION['logged_user'] -> counter; $new_counter = $counter + 1; $user = R::load('users', $id); $user->counter = $new_counter; $_SESSION['logged_user'] -> counter = $new_counter; R::store($user); header('Location: /'); } ?> <html> <head> <link rel="stylesheet" type="text/css" href="/style.css"/> <meta id="metaviewport" name=viewport content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"> </head> <body> <?php echo $result;?> <div class="page page_door" > <?php if(isset($_SESSION['logged_user'])) :?> <div class="account" > Привет, <?php echo $_SESSION['logged_user'] -> login;?>!<br> <form action="/index.php" method="post" > <span><?php echo $_SESSION['logged_user'] -> counter;?></span> <a><button type="submit" name="do_counter" >+1</button></a> </form> <a href="logout.php" ><button class="button_2" >Выйти</button></a> </div> <?php else :?> <form action="/index.php" method="post" > <p><strong>Ник</strong>:</p> <input type="text" name="login" value="<?php echo @$data['login'];?>" > <p><strong>Пароль</strong>:</p> <input type="password" name="password" value="<?php echo @$data['password'];?>" > <a><button type="submit" name="do_login" >Войти</button></a> </form> <a href="signup.php" ><button class="button_2" >Зарегаться</button></a> <?php endif; ?> </div> </body> </html> signup.php PHP: <?php require('db.php'); $data = $_POST; if(isset($data['do_signup'])){ $errors = array(); if(trim($data['login']) == ''){ $errors[] = 'Неправильный ник'; } if(R::count('users', "login = ?", array($data['login'])) > 0){ $errors[] = 'Такой Ник уже существует'; } if($data['day'] == ''){ $errors[] = 'Выберите день'; } if($data['month'] == ''){ $errors[] = 'Выберите месяц'; } if($data['year'] == ''){ $errors[] = 'Выберите год'; } $now = time(); // or your date as well $day = $data['day']; $month = $data['month']; $year = $data['year']; $your_date = strtotime("$year-$month-$day"); $datediff = $now - $your_date; $datareg = $datediff / (60 * 60 * 24) / 365; // echo '<br>'; //$datareg2 = round($datediff / (60 * 60 * 24)); if($datareg < 0){ $errors[] = 'Вы еще не родились ;-)'; } if($datareg <= 5){ $errors[] = 'Вы слишком молоды!'; } if($datareg > 150){ $errors[] = 'Вы слишком взрослые!'; } if(trim($data['password']) == ''){ $errors[] = 'Введите пароль!'; } if(trim($data['password']) != trim($data['password_2'])){ $errors[] = 'Пароли не совпадают'; } if(empty($errors)){ $user = R::dispense('users'); $user->login = trim($data['login']); $user->password = password_hash($data['password'], PASSWORD_DEFAULT); $user->counter = 0; $userreg = '<div style="color:green">Регистрация прошла успешно!<br><a href="/">Перейти на страницу входа</a></div>'; R::store($user); }else{ $result = '<div class="result result_reg">'.array_shift($errors).'</div>'; } } ?> <html> <head> <link rel="stylesheet" type="text/css" href="/style.css"/> <meta id="metaviewport" name=viewport content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"> </head> <body> <?php echo $result;?> <div class="page page_reg" > <form action="/signup.php" method="post" > <p><strong>Ник</strong>:</p> <input type="text" name="login" value="<?php echo @$data['login'];?>" > <p><strong>Когда вы родились?</strong>:</p> <?php // устанавливаем первый и последний год диапазона $dayArray = range(1, 31); ?> <!-- выводим выпадающий список --> <select name="day"> <option value="">День</option> <?php foreach ($dayArray as $day) { // если вы хотите выбрать конкретный год $selected = ($day == @$data['day']) ? 'selected' : ''; echo '<option '.$selected.' value="'.$day.'">'.$day.'</option>'; } ?> </select> <?php // устанавливаем массив месяцев $formattedMonthArray = array( "1" => "01", "2" => "02", "3" => "03", "4" => "04", "5" => "05", "6" => "06", "7" => "07", "8" => "08", "9" => "09", "10" => "10", "11" => "11", "12" => "12", ); ?> <!-- выводим выпадающий список --> <select name="month"> <option value="">Выберите месяц</option> <?php foreach ($formattedMonthArray as $month) { // если вы хотите выбрать конкретный месяц $selected = ($month == @$data['month']) ? 'selected' : ''; // если вы хотите добавить перед номером месяца дополнительный 0, раскомментируйте строку ниже // $month = str_pad($month, 2, "0", STR_PAD_LEFT); echo '<option '.$selected.' value="'.$month.'">'.$month.'</option>'; } ?> </select> <?php // устанавливаем первый и последний год диапазона $yearArray = range(2019, 1850); ?> <!-- выводим выпадающий список --> <select name="year"> <option value="">Выберите год</option> <?php foreach ($yearArray as $year) { // если вы хотите выбрать конкретный год $selected = ($year == @$data['year']) ? 'selected' : ''; echo '<option '.$selected.' value="'.$year.'">'.$year.'</option>'; } ?> </select> <p><strong>Пароль</strong>:</p> <input type="password" name="password" value="<?php echo @$data['password'];?>" > <p><strong>Повторите пароль</strong>:</p> <input type="password" name="password_2" value="<?php echo @$data['password_2'];?>" > <center> <?php echo $userreg; ?> </center> <a><button type="submit" name="do_signup" >Зарегаться</button></a> </form> <a href="/" ><button class="button_2" >Назад</button></a> </div> </body> </html> logout.php PHP: <?php require('db.php'); unset($_SESSION['logged_user']); header('Location: /'); ?> db.php PHP: <?php //Подключаем РедБин require('libs/rb.php'); //Подключаемся к БД R::setup('mysql:host=localhost;dbname=felicity', 'root', ''); //Запкскаем сессии session_start(); ?> style.css Код (CSS): *{ margin:0px; padding:0px; } button { text-decoration:none; height:40px; width:160; cursor:pointer; background-color:green; position:absolute; top:100%; left:0; padding:0; } .button_2{ left:50%; background-color:#696969; } .result{ width:320px; height:50px; top:50%; left:50%; position:relative; background-color:red; border-radius:10px 10px 0px 0px; text-align:center; color:#fff; line-height:40px; } .result_door{ margin:-150px 0px 0px -150px; } .result_reg{ margin:-210px 0px 0px -150px; } .account{ text-align:center; } span{ font-size:100px; line-height:100px; } .page { background-color:#ccc; width:300px; padding:10px; border-radius:10px 10px 0px 0px; position:fixed; top:50%; left:50%; } .page_door{ height:120px; margin:-110px 0px 0px -150px; } .page_reg { height:240px; margin:-170px 0px 0px -150px; } input { width:300px; height:30px; } p{ text-align:left; } И последнее: libs/rb.php - нужно разместить фреймворк RedBeanPHP для безопасной работы с базой. Ссылка https://redbeanphp.com/index.php?p=/download Спасибо за внимание. Жду комментариев)
@mainprofilemail выложи на халявный хостинг какой-нибудь, никто не будет ставить твоё творение к себе на сервер, чтоб посмотреть. По коду. Во-первых, после header("Location ..") обязательно ставить die или exit. Всё равно при получении этого заголовка браузер всё остальное игнорирует, так зачем стараться? А может выполнится лишний код. Во-вторых, на мой взгляд, index.php перегружен разной логикой - и перезапись счётчика в базе, и прохождение аутентификации. Хоть кода и мало, лучше вынести в другие файлы. В-третьих, в сессии обычно хранят только id аутентифицированного юзера, и просто считывают его при каждом запросе. По ID база найдёт пользователя очень быстро. По проверке возраста - твой код пропустит меня, если мне 5 лет и 3 месяца, насколько я вижу. А не должен. Так же нет проверки на корректность даты (31 февраля, к примеру, чтоб отсекало). И есть такая прикольная вещь: https://secure.php.net/manual/ru/function.date-diff.php. Так не стоит делать, вообще, чем меньше собачки, тем лучше. В PHP 7.0 (а я надеюсь ты юзаешь php > 7) для таких вещей есть ??: PHP: <?= $data["login"] ?? ""; ?> По стилям - лучше смотреть в браузере, но в центре экрана я сомневаюсь.
Выкладывал код на zzz.com.ua но у него какие-то тёрки с РедБин'ом не хочет полноценно работать. Сейчас найду другой и скину ссылку) И да по поводу дат там есть лажа так как с ними я работать не умею. А насчёт 5 лет и 3 месяца то указано в задании если я неошибаюсь что не должно регистрировать если меньше 5-ти лет. Одним словом скину ссылку на сайт через некоторое время.
@Dimon2x , @mkramer , @Fell-x27 , закинул на хост))) Вот ссылочка буду раз если ознакомитесь и оставите свои комментарии http://host1735374.hostland.pro. @Dimon2x Спасибо за сайтик)))
@Dimon2x, вот прямо эту задачу непременно надо решать MVC И ещё Laravel какой-нибудь взять Свет клином на MVC не сошёлся, код, не следующий этой парадигме буквально (особенно в традиционном понимании её реализации, с классами-контроллерами), не является априори плохим. --- Добавлено --- P.S. Я когда-то решил эту задачу в MVC-стиле, но у меня свои были мотивы - с новой версией фреймворка Slim поиграться, я на тот момент уже не был новичком.