Как проверить значение переменной php. Variables if - PHP:проверьте, существует ли переменная, но также имеет значение, равное чему-то

Можно проверить, существует ли данная переменная, (то есть инициализирована или она). Для этого используется функция:

Isset(переменная);

Если переменной в данный момент не существует (нигде ранее ей не присваивалось значение или она была удалена функцией unset () ), то функцияisset () возвращаетfalse , в противном случае –true :

$x = 5;

if (isset($x))

echo ‘< BR >Переменная $ x существует, ‘, “ее значение равно $ x < BR >”;

На экране появится:

Переменная $ x существует, ее значение равно 5

Важно помнить, что мы не можем использовать в программе неинициализированную переменную – это породит предупреждение со стороны интерпретатора PHP .

Чтобы выяснить, является ли значение переменнойпустым , используется функция:

empty( переменная);

Если значение переменной равно нулю ,“0”, NULL , пустой строке (“” ),false, переменная не объявлена или являетсяпустым массивом , то эта функция возвращаетtrue , в противном случае –false .

Чтобы проверитьтип переменной, используются функции:

Is_string(переменная);

is _ int (переменная);

is _ float (переменная);

is _ null (переменная);

is _ array (переменная);

is _ numeric (переменная); - если переменная является числовой (integer , float ) или строкой, содержащей только числа.

Эти функции возвращают true , если переменная имеет указанный тип.

Вывод данных

Бесформатный вывод

Бесформатный вывод строк или значений переменных осуществляется функцией:

echo список переменных;

echo строка;

где список переменных – имена выводимых переменных через запятые.

Если мы работаем с веб-браузером, то эта функция направляет вывод в клиентскую часть браузера (в его окно).

Как это уже было сказано, если в строке, заключенной в двойные кавычки, встречаются имена переменных, то на экран вместо этих имен выводятся соответствующие им значения. Более того, если в такой строке встречаются теги HTML (дескрипторы, заключенные в угловые скобки), то браузер отображает этотHTML -код так, как он должен это делать при интерпретацииHTML -документа:

$year = 2012;

$message = “ Желаю всем счастья !”;

echo “

Мои поздравления !

”;

echo “ Наступил $year год !
$message
”;

?>

На экран будет выведен заголовок уровня H 3 и последующее приветствие, причем слово “счастья!” будет выведено полужирным курсивом:

Мои поздравления!

Наступил 2012 год! Желаю всем счастья!

Так можно создавать динамические сайты.

Форматированный вывод

Форматированный вывод позволяет представлять выводимые числа в различных системах счисления, а в десятичной системе – в различных видах (форматах ). Он похож на форматированный вывод вСи и осуществляется функциями:

printf (“формат”, список вывода);

sprintf (“формат”, список вывода);

Первая функция выводит в окно браузера отформатированные данные и возвращает их количество.

Вторая функция только форматирует выводимые данные, но не выводит их.

Формат – это последовательность описателей преобразований для выводимых значений.

Описатель преобразований для каждого значения имеет вид:

% ЗаполнительВыравниваниеДлина.ТочностьТип

- Заполнитель – это символ, который будет использоваться для дополнения результата преобразования до заданнойдлины (по умолчанию –пробел ); если это другой символ, то перед ним ставится одинарная кавычка (апостроф ),

- Выравнивание – по умолчанию – поправому краю поля вывода; если стоит минус (- ), то полевому ,

- Длина – ширина поля вывода - количество знакомест, отводимых для вывода этого значения. Если выводимое значение содержит меньше знакомест, чем заданнаядлина , то оставшееся пространство будет заполненопробелами или символами заполнения,

- Точность – количество десятичных разрядов в дробной части числа,

- Тип – тип выводимого значения:

b двоичное ,

с символ ,

d целое в десятичной системе счисления,

е вещественное в экспоненциальной форме (с плавающей запятой),

f вещественное в форме с фиксированной запятой,

s строка ,

о целое в восьмеричной системе счисления,

x целое в 16-ричной системе счисления.

Пример:

php

$ zarp _1 = 6543.21;

$ zarp _2 = 45321.67;

$ fam _1 = "Балаганов";

$ fam _2 = "Бендер";

printf ("< H 1>Платежная ведомость h 1>");

printf("%".-12s%".10.2f руб.", $fam_1, $zarp_1);

echo "
";

printf("%".-12s%".10.2f руб.", $fam_2, $zarp_2);

echo "
";

?>

В качестве заполнителя была выбрана точка (‘. ) . Фамилии выравниваются по левому краю (- ) в поле шириной12 символов. Числа представляются в форме с фиксированной запятой в поле шириной10 символов и с точностью2 знака после запятой, с выравниванием по правому краю.

Материал предназначен в основном для начинающих веб-программистов.

Введение.

Часто ко мне обращаются клиенты, у которых установлены самописные CMS или модули, написанные начинающими веб-программистами, которые не понимают, что нужно для защиты данных и зачастую копируют функции фильтрации, не задумываясь о том как они работают и что именно нужно с ними делать.

Здесь я постараюсь описать как можно подробнее частые ошибки при фильтрации данных в PHP скрипте и дать простые советы как правильно выполнить фильтрацию данных.

В сети много статей по поводу фильтрации данных, но они как правильно не полные и без подробные примеров.

Разбор полетов.

Фильтрация. Ошибка №1
Для числовых переменных используется такая проверка:
$number = $_GET["input_number"]; if (intval($number)) { ... выполняем SQL запрос... }
Почему она приведет к SQL инъекции? Дело в том, что пользователь может указать в переменной input_number значение:
1"+UNION+SELECT
В таком случаи проверка будет успешно пройдена, т.к. функция intval получает целочисленное значение переменной, т.е. 1, но в самой переменной $number ничего не изменилось, поэтому весь вредоносный код будет передан в SQL запрос.
Правильная фильтрация:
$number = intval($_GET["input_number"]); if ($number) { ... выполняем SQL запрос... }
Конечно, условие может меняться, например если вам нужно получить только определенный диапазон:
if ($number >= 32 AND $number <= 65)

Если вы используете чекбоксы или мультиселекты с числовыми значениями, выполните такую проверку:
$checkbox_arr = array_map("intval", $_POST["checkbox"]);
array_map
Так же встречаю фильтрацию в виде:
$number = htmlspecialchars(intval($_GET["input_number"]));
htmlspecialchars
Или:
$number = mysql_escape_string(intval($_GET["input_number"]));
mysql_escape_string

Ничего кроме улыбки это не может вызвать:)

Фильтрация. Ошибка №2.
Для стринг-переменных используется такая фильтрация:
$input_text = addslashes($_GET["input_text"]);
Функция addslashes экранирует спец. символы, но она не учитывает кодировку БД и возможен обход фильтрации. Не стану копировать текст автора, который описал данную уязвимость и дам просто ссылку Chris Shiflett (перевод можно поискать в рунете).

Используйте функцию mysql_escape_string или mysql_real_escape_string , пример:
$input_text = mysql_escape_string($_GET["input_text"]);
Если вы не предполагаете вхождение html тегов, то лучше всего сделать такую фильтрацию:
$input_text = strip_tags($_GET["input_text"]); $input_text = htmlspecialchars($input_text); $input_text = mysql_escape_string($input_text);
strip_tags - убирает html теги.
htmlspecialchars - преобразует спец. символы в html сущности.
Так вы защитите себя от XSS атаки, помимо SQL инъекции.
Если же вам нужны html теги, но только как для вывода исходного кода, то достаточно использовать:
$input_text = htmlspecialchars($_GET["input_text"]); $input_text = mysql_escape_string($input_text);

Если вам важно, чтобы значение переменной не было пустой, то используйте функцию trim , пример:
$input_text = trim($_GET["input_text"]); $input_text = htmlspecialchars($input_text); $input_text = mysql_escape_string($input_text);

Фильтрация. Ошибка №3.
Она касается поиска в БД.
Для поиска по числам используйте фильтрацию, описанную в первой ошибке.
Для поиска по тексту используйте фильтрацию, описанную во второй ошибке, но с оговорками.
Для того, чтобы пользователь не смог выполнить логическую ошибку, нужно удалять или экранировать спец. символы SQL.
Пример без доп. обработки строки:
$input_text = htmlspecialchars($_GET["input_text"]); // Поиск: "%" $input_text = mysql_escape_string($input_text);
На выходе у нас получится запрос вида:
... WHERE text_row LIKE "%".$input_text."%" ... // WHERE text_row LIKE "%%%"
Это значительно увеличит нагрузку на базу.
В своём скрипте я использую функцию, которая удаляет нежелательные мне символы из поиска:
function strip_data($text) { $quotes = array ("\x27", "\x22", "\x60", "\t", "\n", "\r", "*", "%", "<", ">", "?", "!"); $goodquotes = array ("-", "+", "#"); $repquotes = array ("\-", "\+", "\#"); $text = trim(strip_tags($text)); $text = str_replace($quotes, "", $text); $text = str_replace($goodquotes, $repquotes, $text); $text = ereg_replace(" +", " ", $text); return $text; }
Конечно, не все из выше перечисленных символов представляют опасность, но в моём случаи они не нужны, поэтому выполняю поиск и замену.
Пример использования фильтрации:
$input_text = strip_data($_GET["input_text"]); $input_text = htmlspecialchars($input_text); $input_text = mysql_escape_string($input_text);
Также советую сделать ограничение по количеству символов в поиске, хотя бы не меньше 3-х, т.к. если у вас будет большое количество записей в базе, то поиск по 1-2 символам будет значительно увеличивать нагрузку на БД.
Фильтрация. Ошибка №4.
Не фильтруются значения в переменной $_COOKIE . Некоторые думаю, что раз эту переменную нельзя передать через форму, то это гарантия безопасности.
Данную переменную очень легко подделать любым браузером, отредактировав куки сайта.
Например, в одной известной CMS была проверка, используемого шаблона сайта:
if (@is_dir (MAIN_DIR . "/template/" . $_COOKIE["skin"])){ $config["skin"] = $_COOKIE["skin"]; } $tpl->dir = MAIN_DIR . "/template/" . $config["skin"];
В данном случаи можно подменить значение переменной $_COOKIE["skin"] и вызвать ошибку, в результате которой вы увидите абсолютный путь до папки сайта.
Если вы используете значение куков для сохранения в базу, то используйте одну из выше описанных фильтраций, тоже касается и переменной $_SERVER .
Фильтрация. Ошибка №5.
Включена директива register_globals . Обязательно выключите её, если она включена.
В некоторых ситуациях можно передать значение переменной, которая не должна была передаваться, например, если на сайте есть группы, то группе 2 переменная $group должна быть пустой или равняться 0, но достаточно подделать форму, добавив код:

В PHP скрипте переменная $group будет равна 5, если в скрипте она не была объявлена со значением по умолчанию.
Фильтрация. Ошибка №6.
Проверяйте загружаемые файлы.
Выполняйте проверку по следующим пунктам:
  1. Расширение файла. Желательно запретить загрузку файлов с расширениями: php, php3, php4, php5 и т.п.
  2. Загружен ли файл на сервер move_uploaded_file
  3. Размер файла
Проверка. Ошибка №1.
Сталкивался со случаями, когда для AJAX запроса (например: повышение репутации) передавалось имя пользователя или его ID (кому повышается репутация), но в самом PHP не было проверки на существование такого пользователя.
Например:
$user_id = intval($_REQUEST["user_id"]); ... INSERT INTO REPLOG SET uid = "{$user_id}", plus = "1" ... ... UPDATE Users SET reputation = reputation+1 WHERE user_id = "{$user_id}" ...
Получается мы создаем запись в базе, которая совершенно бесполезна нам.
Проверка. Ошибка №2.
При выполнении различного рода действий (добавление, редактирование, удаление) с данными не забывайте проверять права пользователя на доступ к данной функции и дополнительные возможности (использование html тегов или возможность опубликовать материал без проверки).

Давно исправлял в одном модуле форума подобную ошибку, когда любой пользователь мог отредактировать сообщение администрации.

Проверка. Ошибка №3.
При использовании нескольких php файлов сделайте простую проверку.
В файле index.php (или в любом другом главном файле) напишите такую строчку перед подключением других php файлов:
define ("READFILE", true);
В начале других php файлов напишите:
if (! defined ("READFILE")) { exit ("Error, wrong way to file.
Go to main."); }
Так вы ограничите доступ к файлам.
Проверка. Ошибка №4.
Используйте хеши для пользователей. Это поможет предотвратить вызов той или иной функции путём XSS.
Пример составления хеша для пользователей:
$secret_key = md5(strtolower("http://site.ru/" . $member["name"] . sha1($password) . date("Ymd"))); // $secret_key - это наш хеш
Далее во все важные формы подставляйте инпут со значением текущего хеша пользователя:

Во время выполнения скрипта осуществляйте проверку:
if ($_POST["secret_key"] !== $secret_key) { exit ("Error: secret_key!"); }
Проверка. Ошибка №5.
При выводе SQL ошибок сделайте простое ограничение к доступу информации. Например задайте пароль для GET переменной:
if ($_GET["passsql"] == "password") { ... вывод SQL ошибки... } else { ... Просто информация об ошибке, без подробностей... }
Это позволит скрыть от хакера информацию, которая может ему помочь во взломе сайта.
Проверка. Ошибка №5.
Старайтесь не подключать файлы, получая имена файлов извне.
Например:
if (isset($_GET["file_name"])) { include $_GET["file_name"] .".php"; }
Используйте переключатель

null function (11)

У меня есть (или нет) переменная $_GET["myvar"] исходящая из моей строки запроса, и я хочу проверить, существует ли эта переменная, а также если значение соответствует чему-то внутри моего оператора if:

То, что я делаю и думаю, это не лучший способ сделать:

if(isset($_GET["myvar"]) && $_GET["myvar"] == "something") : сделать что-то

Это простой случай, но представьте себе, что нужно сравнить многие из этих переменных $myvar .

Answers

Это похоже на принятый ответ, но вместо этого использует in_array . Я предпочитаю использовать empty() в этой ситуации. Я также предлагаю использовать новое объявление строкового массива, которое доступно в PHP 5.4.0 +.

$allowed = ["something","nothing"]; if(!empty($_GET["myvar"]) && in_array($_GET["myvar"],$allowed)){..}

Вот функция для проверки сразу нескольких значений.

$arrKeys = array_keys($_GET); $allowed = ["something","nothing"]; function checkGet($arrKeys,$allowed) { foreach($arrKeys as $key) { if(in_array($_GET[$key],$allowed)) { $values[$key]; } } return $values; }

Я использую всю свою собственную полезную функцию exst (), которая автоматически объявляет переменные.

$element1 = exst($arr["key1"]); $val2 = exst($_POST["key2"], "novalue"); /** * Function exst() - Checks if the variable has been set * (copy/paste it in any place of your code) * * If the variable is set and not empty returns the variable (no transformation) * If the variable is not set or empty, returns the $default value * * @param mixed $var * @param mixed $default * * @return mixed */ function exst(& $var, $default = "") { $t = ""; if (!isset($var) || !$var) { if (isset($default) && $default != "") $t = $default; } else { $t = $var; } if (is_string($t)) $t = trim($t); return $t; }

Ну, вы можете обойтись, только if($_GET["myvar"] == "something") поскольку это условие предполагает, что переменная также существует. Если это не так, выражение также приведет к false .

Я думаю, что это нормально делать в условных выражениях, как указано выше. На самом деле никакого вреда.

Мой вопрос: существует ли способ сделать это без объявления переменной дважды?

Нет, нет способа сделать это правильно, не выполняя две проверки. Я тоже это ненавижу.

Один из способов обойти это - это импортировать все соответствующие переменные GET в одну центральную точку в массив или объект определенного типа (большинство из них MVC делают это автоматически) и устанавливают все свойства, которые необходимы позже. (Вместо доступа к переменным запроса через код.)

If (isset($_GET["myvar"]) == "something")

Благодаря Mellowsoon и Pekka, я сделал некоторые исследования здесь и придумал это:

  • Проверяйте и объявляйте каждую переменную как null (если это так) перед началом использования (как рекомендовано):
!isset($_GET["myvar"]) ? $_GET["myvar"] = 0:0;

* ok, это просто, но отлично работает, вы можете начать использовать переменную всюду после этой строки

  • Использование массива для всех случаев:
$myvars = array("var1", "var2", "var3"); foreach($myvars as $key) !isset($_GET[$key]) ? $_GET[$key] =0:0;

* после этого вы можете использовать свои переменные (var1, var2, var3 ... и т. д.),

PS: функция, получающая объект JSON, должна быть лучше (или простая строка с разделителем для взрыва / взрыва);

Лучшие подходы приветствуются:)

ОБНОВИТЬ:

Используйте $ _REQUEST вместо $ _GET, таким образом вы покрываете переменные $ _GET и $ _POST.

Isset($_REQUEST[$key]) ? $_REQUEST[$key] =0:0;

Решение, которое я нашел от игры, это сделать:

If($x=&$_GET["myvar"] == "something") { // do stuff with $x }

Как подскажите, вы можете рассмотреть этот подход:

Required = array("myvar" => "defaultValue1", "foo" => "value2", "bar" => "value3", "baz" => "value4"); $missing = array_diff($required, array_keys($_GET)); foreach($missing as $key => $default) { $_GET[$key] = $default ; }

Вы устанавливаете значения по умолчанию и устанавливаете не получаемые параметры в значение по умолчанию:)

К сожалению, это единственный способ сделать это. Но есть подходы к работе с большими массивами. Например, что-то вроде этого:

$required = array("myvar", "foo", "bar", "baz"); $missing = array_diff($required, array_keys($_GET));

Теперь переменная $ missing содержит список значений, которые требуются, но отсутствуют в массиве $ _GET. Вы можете использовать $ missing array для отображения сообщения посетителю.

Или вы можете использовать что-то вроде этого:

$required = array("myvar", "foo", "bar", "baz"); $missing = array_diff($required, array_keys($_GET)); foreach($missing as $m) { $_GET[$m] = null; }

Теперь каждый требуемый элемент имеет по умолчанию значение по умолчанию. Теперь вы можете использовать if ($ _ GET ["myvar"] == "something"), не беспокоясь о том, что ключ не установлен.

Обновить

Другим способом очистки кода будет использование функции, которая проверяет, установлено ли значение.

Function getValue($key) { if (!isset($_GET[$key])) { return false; } return $_GET[$key]; } if (getValue("myvar") == "something") { // Do something }

почему бы не создать функцию для этого, преобразовать переменную, которую вы хотите проверить, в реальную переменную, например.

Function _FX($name) { if (isset($$name)) return $$name; else return null; }

то вы делаете _FX("param") == "123" , просто мысль

Я нашел (намного) лучший код, чтобы сделать это, если вы хотите проверить что-нибудь в .

If [[ $1 = "" ]] then echo "$1 is blank" else echo "$1 is filled up" fi

Почему все это? Все в существует в Bash, но по умолчанию оно пустое, поэтому test -z и test -n не могут вам помочь.

If [ ${#1} = 0 ] then echo "$1 is blank" else echo "$1 is filled up" fi

Я хочу проверить, существует ли переменная. Теперь я делаю что-то вроде этого:

Try: myVar except NameError: # Do something.

Существуют ли другие способы без исключений?


2018-05-09 13:10

Ответы:

Чтобы проверить наличие локальной переменной:

If "myVar" in locals(): # myVar exists.

Чтобы проверить наличие глобальной переменной:

If "myVar" in globals(): # myVar exists.

Чтобы проверить, имеет ли объект атрибут:

If hasattr(obj, "attr_name"): # obj.attr_name exists.


2018-05-09 13:16

Использование переменных, которые не были определены или установлены (неявно или явно), почти всегда является плохим Любые поскольку это указывает на то, что логика программы не была продумана должным образом и, вероятно, приведет к непредсказуемому поведению.

Следующий трюк, который похож на ваш, будет гарантировать, что переменная имеет некоторые ценность перед использованием:

Try: myVar except NameError: myVar = None # Now you"re free to use myVar without Python complaining.

Тем не менее, я все еще не думаю, что это хорошая идея - на мой взгляд, вы должны реорганизовать свой код, чтобы эта ситуация не возникала.


2018-05-09 13:19

Использование try / except - лучший способ проверить существование переменной. Но почти наверняка лучший способ сделать то, что вы делаете, чем устанавливать / тестировать глобальные переменные.

Например, если вы хотите инициализировать переменную уровня модуля при первом вызове некоторой функции, вам лучше с кодом что-то вроде этого:

My_variable = None def InitMyVariable(): global my_variable if my_variable is None: my_variable = ...


2018-05-09 13:27

для объектов / модулей, вы также можете

"var" in dir(obj)

Например,

>>> class Something(object): ... pass ... >>> c = Something() >>> c.a = 1 >>> "a" in dir(c) True >>> "b" in dir(c) False


2017-10-28 18:39

Простой способ - сначала инициализировать его myVar = None

Затем позже:

If myVar is not None: # Do something


2018-06-04 18:46

Я предполагаю, что тест будет использоваться в функции, аналогичной ответ пользователя97370 , Мне не нравится этот ответ, потому что он загрязняет глобальное пространство имен. Один из способов исправить это - вместо этого использовать класс:

Class InitMyVariable(object): my_variable = None def __call__(self): if self.my_variable is None: self.my_variable = ...

Мне это не нравится, потому что это усложняет код и открывает такие вопросы, как, если это подтвердит шаблон программирования Singleton? К счастью, Python позволил функциям иметь атрибуты какое-то время, что дает нам это простое решение:

Def InitMyVariable(): if InitMyVariable.my_variable is None: InitMyVariable.my_variable = ... InitMyVariable.my_variable = None


2018-03-25 20:31

2018-05-09 13:12

A way that often works well for handling this kind of situation is to not explicitly check if the variable exists but just go ahead and wrap the first usage of the possibly non-existing variable in a try/except NameError.

Похожие публикации