Loading...
AleksandurSeferinkin avatar AleksandurSeferinkin 333 Точки

[Homework] PHP Basics - PHP Syntax - November 2014

Здравейте, колеги от 1во ниво!

С нетърпение чаках да започнем този курс и да си припомня лошото и старо PHP. Като резултат съм готов с домашните и реших да ги споделя с вас!

GitHub

Доста четене в google падна по тези задачи с датите... И останах с впечатлението, че доста лесно се борави с тях, стига да научиш какви неща ти дава php.

 

PS: Кодът е подобрен съобразно препоръките на RoYal!

Тагове:
3
PHP Web Development Basics 27/11/2014 17:38:35
RoYaL avatar RoYaL Trainer 6849 Точки
Best Answer

Имам няколко препоръки за кода ти.

От РНР 5.4 нататък, в глобалскоупа се поддържа const синтаксиса, вместо define. Последния използва стрингове и съответно нямаш autocomplete за константите.

Без значение дали ползваш define() или const, може да достъпиш константа само с името й, без да ползваш constant().

Когато ползваш РНР и HTML на едно, т.е. използваш РНР за темплейтване, е малко грозно да имаш къдрави скобки, особено при затварянето изглежда доста излишно и доста трудно трейсващо се <?php } ?>.

Използвай двуеточие за отваряне на конструкция и end... за затваряне. Например:

<?php for ($i = 0; $i < 5; $i++): ?>

    <p> <?= $row[$i]; ?> </p>

<?php endfor; ?>

 

Не използвай ключовете на масив като константи. РНР сайлънтли евалюира несъществуващи константи до стрингове, но това ще ти създаде главоболие, ако има такава константа. Например:

$_POST[name] ще се превърне до $_POST['name'] както би трябвало да бъде, но също така ще генерира notice грешка. Обаче ако преди това имаш define("name", "john"); ... then... too bad. Това ще се превърне в $_POST['john'] и тогава няма да намери такъв ключ в пост масива.

Когато си в интерполиращ цитат (двойни кавички) и искаш да ползваш индекс от масив имаш три варианта, ако не искаш да получиш T_ENCAPSED_AND_WHITESPACE грешка

1. Да затвориш кавичките и да конкатенираш: "My name is: " . $_POST['name']

2. Да форснеш интерполация на стейтмънт с къдрави скоби: "My name is: {$_POST['name']}"

3. Да използваш някакъв стринг форматър с плейсхолдъри: printf("My name is %s", $_POST['name']);

 

isset() позволява arbitrary number of arguments. Вместо isset($var1) && isset($var2) можеш isset($var1, $var2);

 

10
AleksandurSeferinkin avatar AleksandurSeferinkin 333 Точки

Благодаря за препоръките!

Аз търсих в google точно за този начин на отваряне/затваряне на for цикли, но явно не съм го попитал правилно - ти ми спести доста търсене. :)

Относно масивите в стринговете - няма ли някаква конвенция как да се прави или както ми харесва на мене?

1
RoYaL avatar RoYaL Trainer 6849 Точки

Възможните варианти са доста и по принцип няма една единна конвенция, а зависи от случая.

Когато става въпрос за пример като твоя, обикновено се избягва да се конкатенират стрингове с echo/print syntax-a.

Реално изречението ти е статично, имаш да вмъкнеш някакви променливи, така че би трябвало да изглежда така:

<p>My name is: <?= $myArray['name']; ?> and I am <?= $myArray['age']; ?> years old </p>

Когато например се използва за MySQL query, тогава най-лекият вариант е този с плейсхолдърите. Модерните енджини за връзка с базата (като не броим ORM-ите тук) разчитат на плейсхолдъри:

$query = $stmt->prepare("SELECT id FROM users WHERE name = :name AND age < :age");

$stmt->bindParam("name", $myArray['name']);

$stmt->bindParam("age", $myArray['age']);

 

Що се отнася до достъпването на входните данните от рикуеста (POST, GET, PUT, etc...) модерните фреймуърци използват някакъв wrapper върху суперглобалните и някакъв механизъм за ескейпване, защото почти никога не трябва да се разчита на raw data-та. Дори, например, ако пишеш на Netbeans и кажеш echo $_POST['name'] ще ти каже, че не е добра практика да се използва суперглобалната директно.

Това, естествено, не е обект на курса ви по РНР, но е нещо полезно, ако смяташ занапред да се занимаваш с РНР.

Механизмът, който имплементират, сведен до кратък код би изглеждал нещо такова:

http://pastebin.com/wqTM7cYt

Имаш обект който достъпва рикуеста, обикновено в MVC архитектурите, рикуеста не е суперглобален, а е достъпен само до контролерите. Контролерът може да извика Request обекта, който му е инжектнат и да поиска параметър от там. $this->getRequest()->getPost()->firstName например. Като примерно, преди това на рикуест инжектирания обект му е зададено да използва механизъм за ескейпване - HTML (htmlentities). В примера, който съм направил, съм изнесъл една примерна стратегия за ескейпване, един много прост wrapper около $_POST и съответно инстанцирането на последния. Параметрите вече се поискват само като полета на обекта, и минават задължително през ескейпа. В случая, там където съм направил echo $post->firstName дори и да напишеш във формата <script>alert("asd");</script> ще се ескейпне.

 

P.S.: Май много се отплеснах... :)

4
27/11/2014 14:39:10
AleksandurSeferinkin avatar AleksandurSeferinkin 333 Точки

Благодаря ти за отделеното време и за това, че се опитваш да ме/ни научиш на нещо полезно. Вече съм няколко идеи по-потготвен за курса и за напред - не се знае дали новата година няма да работя като PHP 'програматор'.

Аз винаги съм бил на мнението, че трябва да свикваме с добрите практики още в началото, защото веднъж свикнеш ли с нещо, трудно се отвиква. Това escape-ване със сигурност се прави при всички web apps, които приемат информация от потребителя. Дори да не пиша на php, ще си имам 1 наум, че някога някой ми е споменал нещо за post и get данните!

Примерният ти код ми показа също, че не само for цикли могат да се пишат без къдрави скоби. Направи ми впечатление дефиницията на масивите - в private променливата я инициализираш със [], а в конструктора с array() (default-на стойност, предполагам). Вече имам още неща, за които трябва да прочета.

2
RosenKrumov avatar RosenKrumov 203 Точки

Ето и моето домашно по темата. Скоро ще направя и звездичките.

Github

2
28/11/2014 15:54:57
RoYaL avatar RoYaL Trainer 6849 Точки

1.

//Don't know why "\n" is not working => using "<br>"

 

- Because that's how HTML works. Ако имаш следния HTML код

<p>First line

Second Line

Third line </p>

В браузъра ще се покаже: "First line Second Line Third line"

--------------

2. join() vs. implode()

--------------

3. array_push() vs. [] notation

--------------

4. проверяваш дали Age е numeric а после му слагаш htmlentities? :) Ако очакваш нещо да е число, няма нужда да перформваш стрингова операция върху него. Може имплицитно да кастнеш към съответния тип, флоут или интда речем.

 

4
RosenKrumov avatar RosenKrumov 203 Точки

Ще попрочета какво имаш предвид за 2-ра и 3-та точка, а за 4-та веднага се съгласявам с теб, моя грешка. Ще си поправя кода. Иначе по 1-ва точка, просто гледах лекцията на Наков и той там си ползваше "\n" без проблем, но може нещо да съм недогледал или пропуснал, ще проверя отново.

Благодаря ти за съветите, както и за по-горните коментари, те също ми бяха доста полезни :)

 

EDIT:

Сега видях линковете по 2-ро и 3-то, изглежда алтернативите ти един вид оптимизират малко повечко кода, правилно ли съм разбрал? :)

0
28/11/2014 16:37:52
RoYaL avatar RoYaL Trainer 6849 Точки

"\n" би работило в конзолата, защото конзолната среда интерпретира това за нов ред. От своя страна HTML-а не го интерпретира за нов ред.

За 2. и 3. общо взето да :) Освен оптимиация, която не е толкова важна, са и по-използвания вариант в света на РНР. Рядко ще видиш апликейшън, в който се ползва array_push или join.

1
a.angelov avatar a.angelov 1316 Точки

Раничко за това домашно, но ето и моите решения smile

GitHub

Препоръките и коментарите са добре дошли.

1
RoYaL avatar RoYaL Trainer 6849 Точки

Аз повечето неща съм ги казал на колегите по-горе :) Иска ми се да те посъветвам все пак да не ползваш echo за да принтираш HTML. Затваряй PHP тага и просто пиши HTML, както е показал авторът на темата в неговата задача.

2
a.angelov avatar a.angelov 1316 Точки

Благодаря, ще го имам в предвид за напред smile

0
salih1f1 avatar salih1f1 188 Точки

Здравейте колеги. Ето го и моето домашно. Отворен съм към градивна критика и съвети. 

GITHUB

П.П. Задачите със звездичка ще са готови до утре.

1
28/11/2014 23:30:12
VenelinGrozev avatar VenelinGrozev 130 Точки

Да отбележа само, че в 8ма задача в условието се иска да се ползва getdate() функцията за да вземеш текущата дата.

0
a.angelov avatar a.angelov 1316 Точки

Уточнявай кого имаш в предвид, че доста хора са постнали решения :) /видях, че за автора на темата става въпрос/

0
AleksandurSeferinkin avatar AleksandurSeferinkin 333 Точки

Наясно съм с това, но с DateTime клас-а ми изглежда по-елегантно. Също така предпочитам да наблягам към обектно-ориентираното програмиране. Не ми пречеше да взема стойностите от getdate(), които да ги сложа в конструктора на DateTime, но според мен не си заслужава.

0
VenelinGrozev avatar VenelinGrozev 130 Точки

Не съм се и съмнявал, че можеш да вземеш стойностите от getdate(), просто реших да отбележа.

Съжалявам ако прозвуча дребнаво smile

А иначе решението ти за Lazy Sundays много ми хареса - доста е елегантно.

1
30/11/2014 08:45:30
a.angelov avatar a.angelov 1316 Точки

Един коментар по 7-ма задача ще си позволя:

Гледах следващата лекция от курса: Working with forms - там е казано, че escape-ването се прави само и единствено, когато се извежда/принтира информацията в html-а, а не при четенето й /има и още няколко правила изброени.../.

Тоест не тук:

$name = htmlspecialchars($_GET["name"]);

а тук: 

<p>My name is <?= htmlspecialchars($name) ?>

4
29/11/2014 17:58:36
velio84 avatar velio84 241 Точки

Fixed :)

благодаря за уточнението!

1
ibakyrdjiev avatar ibakyrdjiev 172 Точки

Ето и моите задачи :) Всякакви мнения и препоръки са добре дошли :)

Github

2
a.angelov avatar a.angelov 1316 Точки

Здравей,

1. По задача 3 - не си изпълнил всички изисквания в условието - трябва да имаш проверка какъв тип данни ти е променливата и според типа да съответно да принтваш var_dump на променливата ако е числов тип, а за останалите типове променливи трябва да ти принтва типа им - тоест gettype($variable);

2. По задача 7 - защо проверяваш само sex дали е isset, ами ако name и age не са?

3
quickben avatar quickben 966 Точки
<input type="text" name="name" placeholder="Name" required="required">
requiered гарантира, че трябва да има въведена стойност, доста по-удобно е от това да хвърляш exceptioni или да правиш проверки с if statement, a на задача №3 не е задължително да се изпозлзва gettype($variable); след като и със var_dump се изкарват правилни резултати по следния начин:
$values = array(['hello', 15, 1.234, array(1,2,3),  (object)[2,34]]);
for($i = 0; $i < count($values); $i++) {
print_r(var_dump($values[$i]));
}

:)


2
AleksandurSeferinkin avatar AleksandurSeferinkin 333 Точки

quickben, идеята е да пишем php, не html. Ако изтрия това required от html-а, веднага ще се бъгне сайта - с други думи php кодът ти има пропуски! :)

2
devil619 avatar devil619 62 Точки

Ето го и моето домашно без звездичките >> GitHub . Коментари/препоръки/забележки са добре дошли :)


1
30/11/2014 01:30:16
ibakyrdjiev avatar ibakyrdjiev 172 Точки

Благодаря и аз за полезния отговор. Добрите практики от хората с повече опит винаги са добре дошли. Изреждането на стейтмънти със запетайка никога нямаше да се сетя че ще работи!

Поздрави!

1
Krissycherrybomb avatar Krissycherrybomb 5 Точки

А на 2-ра задача (SumTwoNumbers) , не е ли възможно да вкараме всичко в една функция като в Javascript или трябва за всяко едно по отделно да слагаме input-и и да го смятаме?

<?php
function sumNumbers() {
$firstNumber = 
$secondNumber = 
$sum = $firstNumber + $secondNumber;
$sum = number_format($sum, 2);
echo '$firstNumber + $secondNumber = ' . "$firstNumber + $secondNumber = " . $sum;
}
sumNumbers(2,7);
sumNumbers(1.567808,0.356);
sumNumbers(1234.5678,333);
?>

нещо подобно , но не знам как ще бъдат извикани променливите..

1
a.angelov avatar a.angelov 1316 Точки

Защо да не може :)

Просто подай параметри на функцията - function sumNumbers($a, $b) например.

1
quickben avatar quickben 966 Точки
<?php
function sumNumbers($first, $second) {
$firstNumber = $first;
$secondNumber = $second;
$sum = $firstNumber + $secondNumber;
$sum = number_format($sum, 2);
echo '$firstNumber + $secondNumber = ' . "$firstNumber + $secondNumber = " . $sum;
}
sumNumbers($_GET['first'], $_GET['second']);
?>

Някой по-напреднал да каже, иначе кода по-горе взима данни от html...
ps - ако смяташ да постваш по-дълъг код е хубаво да се upload-не в някой сайт.
2
01/12/2014 23:33:51
quickben avatar quickben 966 Точки

a.angelov за да не спамя отделно може ли да те попитам дали вече съм направил като хората задача №3, че както правилно отбеляза само при определни случай трябва да се използва var_dump в съотвената задача -> ЦЪК

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.