Криене на бутон за текущ потребител

vinsbg

Registered
Това ли е правилния начин за криене на бутон на текущия ( логнатия ) потребител или има друг "по-елегантен" начин?

Код:
if($_SESSION['id'] == $row['user_id'])
{ 
     echo '<div style="display:none;"> Бутон </div>'; 
} 
else 
{
     echo '<div> Бутон </div>';
}
 
Вместо display none на първото echo можеш и да го оставиш празно , но според мен няма "по-елегантен" начин. Аз по същата логика ползвам тези SESSION-и
 
cr0uch3rr каза:
Вместо display none на първото echo можеш и да го оставиш празно , но според мен няма "по-елегантен" начин. Аз по същата логика ползвам тези SESSION-и

Просто винаги, когато използвам SESSION се притеснявам.. не знам защо.. Може би, защото все още не ги разбирам тия сесии много добре :)
 
PHP:
<?
function za6titi($tekst)
{
if ( (int)$tekst )
return $tekst;
else
{
$tekst = addslashes($tekst);
$tekst = htmlspecialchars($tekst, ENT_NOQUOTES);
return $tekst;
}
}
$_SESSION = @array_map("za6titi", $_SESSION);
$_COOKIE = @array_map("za6titi", $_COOKIE);
$_SERVER = @array_map("za6titi", $_SERVER);
?>

Ето ти код който защитава SESSION-ите , $_POST и $_GET
 
Благодаря..

А това в нов файл, който трябва да се инклудне във всеки файл, в който се използват ли?
 
Да,но ако използваш switch в index който прави линковете нещо подобно на index.php?p= го инклудни направо в индекса
 
Колеги, никога не защитавайте така глобални променливи. Първо! Ако някъде в приложението Ви се наложи да използвате нефилтрирана променлива, то това води до куп проблеми. Второ. Каква е тази НЕ индивидуална защита? Какво прави функцията в момента? Тя проверява дали е подадено число и го филтрира целочислено, а ако е подаден стринг през addslashes и htmlspecialchars. Ако имате число double или float нали ще отреже само целочислената част. В много от случаите просто ще преминавате към филтриране на стринг защото ако имате един рутер и примерно на страницата на сайта си имате някаква категория ?id=1 то ако подам ?id=1' ще го приеме за стринг и ще ти го обработи, докато на теб тогава ще ти е нужна просто int проверка и трескане на грешка. Изобщо да филтрирате така масивите е пълна глупост за мен. Там където Ви се налага да използвате някакъв параметър то ТАМ ВИЕ трябва да укажете какъв да бъде той, а не да филтрирате масово и ненужно. Да не говорим отделно за време, защото обработката на три малки масива с вградената функция array_map не е толкова бързо отколкото примерно с цикъл foreach. Сметнете ако Ви се налага някъде из кода да въведете огромно количество информация и перформънса ще стане много тежък. А и какво правите с тази функция ако случайно сесията приеме масив? Веднага ще тресне грешка, защото array_map не обхожда recursive тоест масиви в масива и ще тресне грешка. :)
 
Потвърждение за даката и забележка към кода на cr0uch3rr

PHP:
if ( (int)$tekst )

това е много грешно (в случая). Превръщаш в инт, за да провериш дали е bool true? Логически няма смисъл. В случая се ползва http://php.net/manual/en/function.ctype-digit.php

PHP:
if(ctype_digit($text))

Защото!
Отговорете си сами какво ще стане при този инпут:
Код:
123<hacking></text>

По въпроса на vinsbg:
Това ли е правилния начин за криене на бутон на текущия ( логнатия ) потребител или има друг "по-елегантен" начин?
Криене на бутон? Ако искаш да го скриеш, защо изобщо го показваш? Защо изобщо трябва да има "div display=none" в страницата?

В случая най-правилно ще бъде

PHP:
if(empty($_SESSION['id'])) {
    echo '<div> Бутон </div>';
}

ЗАЩО не сравнявам със стойността от базата? Защото сесията си я създал ти с пълната увереност, че съществува потребител с такова id. Вероятно ще попитате - ако по някаква причина по време на сесията потребителят изчезне от базата, няма ли горният код да дава true? В такъв случай трябва да се изтрие сесията (session_destroy).
Защо ползвам empty? Защото проверява за isset и true едновременно, без да дава грешка при несъществуваща променлива.
 
Да! Аз също подкрепям anonimen в думите му. Те са едно чудесно допълнение и разширение на обосновката ми по-нагоре. Благодаря, че си разширил забележката ми с доста примери. :) :?:
 
anonimen каза:
Защото!
Отговорете си сами какво ще стане при този инпут:
Код:
123<hacking></text>


Ще върне 0, което е false. Конкретен отговор, на конкретен въпрос.

Друг е въпроса цялостната логика.


До автора. Преди да сетваш каквито и да е сесии, то се уверявай, че данните, които си получил са верни. Т.е., трябва да правиш проверките на по-горно ниво.

Аз бих ползвал filter_input_array().

Пример по примера в документацията.

Проста регистрация:

PHP:
$args = [
       'username' => [
                'filter' => FILTER_SANITIZE_STRING,
                'options' => [ 'min_range' => 4, 'max_range' => 16]
       ],

       'email' => FILTER_VALIDATE_EMAIL,

       'password' => [
                 'filter' => FILTER_SANITIZE_STRING,
                 'options' => [ 'min_range' => 3, 'max_range' => 20 ]
       ]
];

$filter = filter_input_array(INPUT_POST, $args);

if ( is_array($filter) ) {
    // всичко е точно и сетваме сесии
}

ЕДИТ: След това не взимай стойностите директно от $_POST и да ги сетваш. Взимай ги от $filter масива.
 
Revelation каза:
anonimen каза:
Защото!
Отговорете си сами какво ще стане при този инпут:
Код:
123<hacking></text>


Ще върне 0, което е false. Конкретен отговор, на конкретен въпрос.

Друг е въпроса цялостната логика.


До автора. Преди да сетваш каквито и да е сесии, то се уверявай, че данните, които си получил са верни. Т.е., трябва да правиш проверките на по-горно ниво.

Аз бих ползвал filter_input_array().

Пример по примера в документацията.

Проста регистрация:

PHP:
$args = [
       'username' => [
                'filter' => FILTER_SANITIZE_STRING,
                'options' => [ 'min_range' => 4, 'max_range' => 16]
       ],

       'email' => FILTER_VALIDATE_EMAIL,

       'password' => [
                 'filter' => FILTER_SANITIZE_STRING,
                 'options' => [ 'min_range' => 3, 'max_range' => 20 ]
       ]
];

$filter = filter_input_array(INPUT_POST, $args);

if ( is_array($filter) ) {
    // всичко е точно и сетваме сесии
}

ЕДИТ: След това не взимай стойностите директно от $_POST и да ги сетваш. Взимай ги от $filter масива.

Да така е но реално това е вече, за доста напреднали и за определени ситуации. Смисъл за простите случаи дори да взимаш директно примерно от $_POST тоест $promenliva = $_POST['pole']; тук трябва да извършваме някаква дейност. Тук трябва да знаем винаги каква стойност ще приема променливата, по-точно видът и. Няма как да ни трябва число и да получаваме стринг, след което да обработваме в базата стринг било той филтриран или не. Вярно е, че трябва да има защити на много нива. При ООП това се постига много лесно и неусетно с проверките в методите. Реално на мястото на присвояването то там трябва да указваме очакваната стойност. Наистина може за някой приложения в променливите да се очакват определени типове стойности, но глобално проверяване и променяне на глобален масив е грешна практика. В случая ти даваш едно хитро решение с присвояване на обработеният масив на променлива и запазване на оригинала. Е да така пък се пълни паметта но честно казано за мен основно както каза и анонимен е хубаво да се прави на място. Все пак аз в масив $_POST може да имам индекси(ключове) от 0 до 10 с някаква информация, но реално да ползвам само 1. Тоест $_POST['1'] което означава, че само за него ще указвам какво ми трябва и какво трябва да се филтрира. Имайте в предвид, че потребителят може да е гадно същество. На никого не му пречи да отвори бразъра да добави поле във формата с някакво име и да изпрати куп простотиии с куп имена в променливата $_POST. Масива ще съдържа тези данни, но няма да бъдат използвани и при следващият рефреш ще са унистожени, но ако ние филтрираме масива, то тогава ще се отрази на цялостното представяне на сайта, защото перформънса ще бъде нарушен. Всеки решава за себе си естествено, но практиката е доказала, че на потребител доверие не трябва да имаш. :?: :?: :?:
 
Не е точно така, както описваш случая, който съм дал. При моя случай променливата $filter съдържа само това, което е описано в масива. Т.е. няма как да не знаеш за една регистрация или вход как трябва да си филтрираш данните. Задаваш условия, изпълнява ги и ти връща масив с филтрираните данни. Ако подадеш директно глобалния масив, ти реално пускаш нефилтрираните данни.

Дори и да подаде други параметри филтъра ще ги отчете като null, а ако се зададе един от предоставените флагове(не помня точно как се пишеше), това което го няма описано в масива за филтриране го отчита и дава false.

Колкото за паметта — стига глупости де. Това не влияе с нищо, на всичкото отгоре данните се трият от паметта след като смениш страницата.
Това което прави филтър функцията е същото, което трябва да се прави и при ръчна проверка.
Отворете някоя книга за защита и ще видите следното.

PHP:
$filter =  [];

if ( ТУКА ПРОВЕРКА ЗА ВАЛИДНА ПОЩА ) {
        $filter['email'] = $_POST['email'];
}
 
Revelation каза:
anonimen каза:
Защото!
Отговорете си сами какво ще стане при този инпут:
Код:
123<hacking></text>


Ще върне 0, което е false. Конкретен отговор, на конкретен въпрос.
Не. Току що тествах. Връща 123, което е true.

PHP:
<?php
$da = "123<hack></text>";
echo ((int) $da);

http://ideone.com/ObO4Jp#
 
Revelation каза:
Не е точно така, както описваш случая, който съм дал. При моя случай променливата $filter съдържа само това, което е описано в масива. Т.е. няма как да не знаеш за една регистрация или вход как трябва да си филтрираш данните. Задаваш условия, изпълнява ги и ти връща масив с филтрираните данни. Ако подадеш директно глобалния масив, ти реално пускаш нефилтрираните данни.

Дори и да подаде други параметри филтъра ще ги отчете като null, а ако се зададе един от предоставените флагове(не помня точно как се пишеше), това което го няма описано в масива за филтриране го отчита и дава false.

Колкото за паметта — стига глупости де. Това не влияе с нищо, на всичкото отгоре данните се трият от паметта след като смениш страницата.
Това което прави филтър функцията е същото, което трябва да се прави и при ръчна проверка.
Отворете някоя книга за защита и ще видите следното.

PHP:
$filter =  [];

if ( ТУКА ПРОВЕРКА ЗА ВАЛИДНА ПОЩА ) {
        $filter['email'] = $_POST['email'];
}

Да така е. Пропуснал си да разбереш, че бях съгласен с теб. Но както са дали колегите горе:
PHP:
function za6titi($tekst)

{

if ( (int)$tekst )

return $tekst;

else

{

$tekst = addslashes($tekst);

$tekst = htmlspecialchars($tekst, ENT_NOQUOTES);

return $tekst;

}

}

$_SESSION = @array_map("za6titi", $_SESSION);

$_COOKIE = @array_map("za6titi", $_COOKIE);

$_SERVER = @array_map("za6titi", $_SERVER);


$_POST = @array_map("za6titi", $_POST);

То ако напълня една форма с огромен брой инпут полета като подавам огромен брой масиви данни и прочие, то array_map("za6titi", $_POST); ще накара страницата на хостига да зарежда много бавно. Тоест потребителя има вероятност неволно докато се опитва да качва нещо или пише да направи беля и да се откаже по простата причина, че страницата ще му зарежда много бавно. Много е относително и повярвай ми ако не си си правил тестове с цикли на безплатни хостинги, то ще разбереш, че там има ограничено процесорно време. Страниците зареждат по-бавно и ред други дивотии. Влиянието може да е многозначително ако се открие такава слабост и се напълни сървъра с заявки. Тоест тогава си с една идея по-открит за атаки товарещи машината. Както и да е дано някой, ме е разбрал какво имам предвид. Не ми се обяснява излишно. Да трие се но това е друга тема. Впрочем изкарвал съм грешка за time_limit в аналогични случаи. Ако не се лъжа по памет цитирам, мисля, че атаката се наричаше DOS (https://bg.wikipedia.org/wiki/%D0%90%D1%82%D0%B0%D0%BA%D0%B0_%D0%B7%D0%B0_%D0%BE%D1%82%D0%BA%D0%B0%D0%B7_%D0%BD%D0%B0_%D1%83%D1%81%D0%BB%D1%83%D0%B3%D0%B0) но пак казвам не съм сигурен (или беше CSRF). Както и да е няма значение. По принцип при всяко положение в някой случаи потребителя неволно може да влезе в едно чакане и зареждане на страницата. В случая Стефчо с теб говорим за различни неща. Твоят код е правилено структуриран и логически издържан, но тяхният не е. Само за паметта ще ти дърпам ушите, че там или не си ме разбрал (все пак не давам код ако дам някакъв пример ще ме разбереш) или си мислиш за друга ситуация. При всяко положение с теб водим винаги интересни теми :D :D :D :?:
 
@anonimen, прав си. Грешката е моя.

Дака, аз говоря за конкретно случая на @vinsbg. Проверките, които той прави са в много крайно ниво и то проверка, която проверява дали в сесията е записан запис, който съществува.
За това се отнасяше моя коментар, че конкретно в този случай, когато му трябва да проверява сесията, то проверката трябва да я прави на по-горно ниво.
Реално аз съм дал пример с регистрация. Той трябва да я прави при вход преди да я сетне.

Прави си филтрацията, ако филтрацията мине, връща му масив с обработените данни, след което трябва да ползва тях данни, за да направи например проверка в базата данни дали съществува конкретния потребител. Ако съществува сетва сесиите.

Иначе, това за което говориш би трябвало да е за CSRF, с което могат да се манипулират сесиите. За това нещо трябва да прочете в интернет. DDoS е другата атака, това е многократно изпращане на заявки към сървъра, което го довежда до краш, защото не може да ги обработи(може и това да си имал предвид).

Това, което дадоха като код, си прав, не е правилно. Чисто безсмислено.

Относно паметта, не знам дали говорим на различни теми, но винаги използвам едни и същи изрази, че ако кода е структуриран правилно, то няма какво да се гледа паметта. Там където се изисква голямо процесорно време се прави кеш, ако не е възможен кеш, се търси алтернатива или фиксване на кода. Те за това са и тестовете. Няма безгрешни хора и не може кода от първия път да е изцяло изпипан отвсякъде.
Паметта главно се пълни от безкрайни цикли, а това е грешка на програмиста, че е допуснал някъде си това да бъде изпълнено.

При конкретния случай, за който е основно темата и за който аз отговорих с първия си пост, се отнасяше за това как да си чистим и валидираме данните. А именно, пак да кажа, за да е сигурен, че сесията е коректна, то трябва да се направят нужните филтрации и проверки още при вход. Ако не преминат проверките, не допускаме да се създаде сесия. А за да няма манипулирания(това не е на 100% подсигурено), се прави CSRF токен, за който автора трябва да почете малко, за да види как да се справи.

Иначе проверки за определени ситуации естествено, че трябва да се правят. Но дори една ГЕТ заявка може да се обработи с filter_var или filter_input, вместо ctype_digit(). ctype_digit() те подсигурява дали подадените данни са число, докато с филтъра можеш директно да му зададеш условията, при които трябва да допусне данните.
 

Back
Горе