isset () 및 empty ()를 피하는 방법
PHPisset () 및 empty ()를 피하는 방법
변수의 존재가 isset ()과 consort를 사용하여 명시 적으로 검사되지 않았기 때문에 E_NOTICE 오류 수준에서 실행될 때 "xyz is undefined"및 "undefined offset"메시지를 많이 던지는 여러 오래된 응용 프로그램이 있습니다.
누락 된 변수 나 오프셋에 대한주의 사항이 생명의 은인 일 수 있고 약간의 성능 향상이있을 수 있으며 전반적으로 더 깨끗한 방법이므로 E_NOTICE와 호환되도록 노력하고 있습니다.
그러나, 나는 isset ()과 array_key_exists ()가 내 코드에하는 영향을 좋아하지 않는다. 그것은 부 풀리게되고, 가치 또는 의미면에서 아무것도 얻지 않고 읽기가 어려워집니다.
변수 검사를 초과하지 않고도 E_NOTICE와 호환되는 동안 어떻게 코드를 구조화 할 수 있습니까?
해결법
-
==============================
1.관심있는 사람들을 위해, 나는이 주제를 약간 더 나은 구조화 된 형태로 아래의 정보를 제공하는 작은 기사로 확장했다. PHP의 확실한 안내서 및 비어 있음
관심있는 사람들을 위해, 나는이 주제를 약간 더 나은 구조화 된 형태로 아래의 정보를 제공하는 작은 기사로 확장했다. PHP의 확실한 안내서 및 비어 있음
IMHO 당신은 앱을 "E_NOTICE compatible"로 만드는 것뿐만 아니라 모든 것을 재구성하는 것에 대해 생각해야합니다. 존재하지 않는 변수를 정기적으로 사용하려고하는 코드에 수백 가지 포인트가 있으면 오히려 심하게 구조화 된 프로그램처럼 들릴 수 있습니다. 존재하지 않는 변수에 액세스하려는 시도는 절대로 일어나지 않아야합니다. 다른 언어에서는 컴파일 타임에이 작업을 중단해야합니다. PHP가 그렇게 할 수 있다고해서 꼭해야한다는 것은 아닙니다.
이 경고는 당신을 괴롭히지 않고 당신을 도울 것입니다. "존재하지 않는 무언가로 작업하려고 시도 중입니다!"라는 경고를받는다면 반응은 "죄송합니다. 내 잘못, 최대한 빨리 해결하겠습니다." "잘 정의되지 않은 변수"와 심각한 오류를 유발할 수있는 정직하지 못한 코드의 차이점을 어떻게 알 수 있습니까? 또한 항상 오류보고를 11로 설정하여 개발하고 단일주의 사항이 발행 될 때까지 코드에 계속 표시되도록하는 이유이기도합니다. 오류보고 기능을 해제하면 프로덕션 환경에서만 정보 누출을 방지하고 버그가있는 코드가있는 경우에도 더 나은 사용자 환경을 제공합니다.
정교하게 :
코드에서 어딘가에 항상 비어 있거나 빈 공간이 필요합니다. 변수를 제대로 초기화하는 유일한 방법은 변수를 올바르게 초기화하는 것입니다. 상황에 따라 다양한 방법이 있습니다.
함수 인수 :
function foo ($bar, $baz = null) { ... }
함수를 설정했기 때문에 $ bar 또는 $ baz가 설정되었는지 확인할 필요가 없습니다. 값을 true 또는 false (또는 다른 값)로 평가하면 걱정할 필요가 있습니다.
어디에서나 정규 변수 :
$foo = null; $bar = $baz = 'default value';
변수를 사용할 코드 블록의 맨 위에서 변수를 초기화하십시오. 이것은! isset 문제를 해결하고 변수가 항상 알려진 기본값을 가지도록 보장하며 독자가 다음 코드가 작동 할 것이고 그에 따라 일종의 자체 문서화 역할을한다는 아이디어를 제공합니다.
배열 :
$defaults = array('foo' => false, 'bar' => true, 'baz' => 'default value'); $values = array_merge($defaults, $incoming_array);
위에서와 같은 것은 배열을 기본값으로 초기화하고이를 실제 값으로 덮어 쓰는 것입니다.
나머지 경우에는 컨트롤러에서 설정하거나 설정하지 않은 값을 출력하는 템플릿을 예로 들어 보겠습니다.
<table> <?php if (!empty($foo) && is_array($foo)) : ?> <?php foreach ($foo as $bar) : ?> <tr>...</tr> <?php endforeach; ?> <?php else : ?> <tr><td>No Foo!</td></tr> <?php endif; ?> </table>
array_key_exists를 정기적으로 사용하고 있다면, 그것을 사용하고있는 것을 평가해야합니다. 차이를 만드는 유일한 시간은 여기에 있습니다.
$array = array('key' => null); isset($array['key']); // false array_key_exists('key', $array); // true
위에서 언급했듯이 변수를 올바르게 초기화하는 경우 키가 있는지 여부를 알 필요가 없으므로 키가 존재하는지 여부를 확인할 필요가 없습니다. 외부 소스에서 배열을 가져 오는 경우 값은 null이 아니지만 ', 0,'0 ', false 또는 이와 비슷한 값, 즉 isset 또는 empty로 평가할 수있는 값, 즉 의지. 배열 키를 정기적으로 null로 설정하고 false를 의미하도록하려면 위의 예에서 isset 및 array_key_exists의 서로 다른 결과가 프로그램 논리에 영향을 주면 왜 그런지 물어보십시오. 변수의 단순한 존재는 중요하지 않아야하며, 그 값만이 중요합니다. 키가 true / false 플래그 인 경우, null이 아닌 true 또는 false를 사용하십시오. 이것에 대한 유일한 예외는 null을 의미하는 제 3 자 라이브러리이지만, PHP에서 null을 검출하기가 어렵 기 때문에 아직이 라이브러리를 찾지 못했습니다.
-
==============================
2.그것을위한 함수를 작성하십시오. 같은 것 :
그것을위한 함수를 작성하십시오. 같은 것 :
function get_string($array, $index, $default = null) { if (isset($array[$index]) && strlen($value = trim($array[$index])) > 0) { return get_magic_quotes_gpc() ? stripslashes($value) : $value; } else { return $default; } }
당신은 다음과 같이 사용할 수 있습니다.
$username = get_string($_POST, 'username');
get_number (), get_boolean (), get_array () 등과 같은 사소한 것들에 대해서도 같은 작업을 수행하십시오.
-
==============================
3.이 문제를 극복하는 최선의 방법 중 하나는 클래스를 통해 GET 및 POST (COOKIE, SESSION 등) 배열의 값에 액세스하는 것입니다.
이 문제를 극복하는 최선의 방법 중 하나는 클래스를 통해 GET 및 POST (COOKIE, SESSION 등) 배열의 값에 액세스하는 것입니다.
각 배열에 대한 클래스를 만들고 __get 및 __set 메서드를 선언합니다 (오버로드). __get은 값의 이름이 될 인수 하나를 허용합니다. 이 메소드는 isset () 또는 empty ()를 사용하여 해당 글로벌 배열에서이 값을 확인하고 값이 존재하면 null을 반환하고 그렇지 않으면 null을 반환해야합니다.
그 후에는 $ POST-> username과 같은 배열 값에 자신있게 액세스 할 수 있으며 필요한 경우 isset () 또는 empty ()를 사용하지 않고 모든 유효성 검사를 수행합니다. username이 대응하는 글로벌 배열 내에 존재하지 않는 경우는 null가 돌려 주어져 경고 또는 통지가 생성되지 않습니다.
-
==============================
4.array_key_exists ()를 사용해도 상관 없습니다. 실제로는 빈 함수와 isset (감수성을 피하기위한 strikedthrough)와 같은 미래의 행동을 바꿀 수있는 해킹 함수에 의존하기보다는이 특정 함수를 사용하는 것을 선호합니다.
array_key_exists ()를 사용해도 상관 없습니다. 실제로는 빈 함수와 isset (감수성을 피하기위한 strikedthrough)와 같은 미래의 행동을 바꿀 수있는 해킹 함수에 의존하기보다는이 특정 함수를 사용하는 것을 선호합니다.
그렇지만이 기능과 배열 인덱스를 다루는 다른 몇 가지 상황에서 편리하게 사용할 수있는 간단한 함수를 사용합니다.
function Value($array, $key, $default = false) { if (is_array($array) === true) { settype($key, 'array'); foreach ($key as $value) { if (array_key_exists($value, $array) === false) { return $default; } $array = $array[$value]; } return $array; } return $default; }
다음과 같은 배열을 가지고 있다고 가정 해 보겠습니다.
$arr1 = array ( 'xyz' => 'value' ); $arr2 = array ( 'x' => array ( 'y' => array ( 'z' => 'value', ), ), );
배열에서 "가치"를 어떻게 얻습니까? 단순한:
Value($arr1, 'xyz', 'returns this if the index does not exist'); Value($arr2, array('x', 'y', 'z'), 'returns this if the index does not exist');
우리는 이미 단층 및 다차원 배열을 다뤘습니다. 그 외에 무엇을 할 수 있습니까?
예를 들어 다음 코드 조각을 가져옵니다.
$url = 'https://stackoverflow.com/questions/1960509'; $domain = parse_url($url); if (is_array($domain) === true) { if (array_key_exists('host', $domain) === true) { $domain = $domain['host']; } else { $domain = 'N/A'; } } else { $domain = 'N/A'; }
꽤 지루한가요? 다음은 Value () 함수를 사용하는 또 다른 접근법입니다.
$url = 'https://stackoverflow.com/questions/1960509'; $domain = Value(parse_url($url), 'host', 'N/A');
추가 예제로 RealIP () 함수를 사용하여 테스트를 수행하십시오.
$ip = Value($_SERVER, 'HTTP_CLIENT_IP', Value($_SERVER, 'HTTP_X_FORWARDED_FOR', Value($_SERVER, 'REMOTE_ADDR')));
-
==============================
5.난 당신과 함께 여기 있어요. 그러나 PHP 디자이너들은 그것보다 훨씬 더 나쁜 실수를 저질 렀습니다. 모든 값 독서에 대한 사용자 정의 함수를 정의하는 것만으로는 부족합니다.
난 당신과 함께 여기 있어요. 그러나 PHP 디자이너들은 그것보다 훨씬 더 나쁜 실수를 저질 렀습니다. 모든 값 독서에 대한 사용자 정의 함수를 정의하는 것만으로는 부족합니다.
-
==============================
6.나는이 기능을 사용한다.
나는이 기능을 사용한다.
function load(&$var) { return isset($var) ? $var : null; } function POST($var) { return isset($_POST[$var]) ? $_POST[$var] : null; }
예제들
$y = load($x); // null, no notice // this attitude is both readable and comfortable if($login=POST("login")) // really =, not == if($pass=POST("pass")) if($login=="Admin" && $pass==...) { // login and pass are not empty, login is "Admin" and pass is ... $authorized = true; ... }
-
==============================
7.설정되지 않은 경우 false를 반환하는 함수를 만들고, 지정된 경우 비어 있으면 false를 반환합니다. 유효하면 변수를 리턴합니다. 아래 코드와 같이 옵션을 추가 할 수 있습니다.
설정되지 않은 경우 false를 반환하는 함수를 만들고, 지정된 경우 비어 있으면 false를 반환합니다. 유효하면 변수를 리턴합니다. 아래 코드와 같이 옵션을 추가 할 수 있습니다.
<?php function isset_globals($method, $name, $option = "") { if (isset($method[$name])) { // Check if such a variable if ($option === "empty" && empty($method[$name])) { return false; } // Check if empty if ($option === "stringLength" && strlen($method[$name])) { return strlen($method[$name]); } // Check length of string -- used when checking length of textareas return ($method[$name]); } else { return false; } } if (!isset_globals("$_post", "input_name", "empty")) { echo "invalid"; } else { /* You are safe to access the variable without worrying about errors! */ echo "you uploaded: " . $_POST["input_name"]; } ?>
-
==============================
8.Null 병합 연산자에 오신 것을 환영합니다.
Null 병합 연산자에 오신 것을 환영합니다.
$field = $_GET['field'] ?? null;
PHP는 말합니다 :
-
==============================
9.가독성에 대한 정의가 무엇인지 모르겠지만 empty (), isset () 및 try / throw / catch 블록을 올바르게 사용하는 것이 전체 프로세스에서 매우 중요합니다. E_NOTICE가 $ _GET 또는 $ _POST에서 오는 경우, 그 데이터가 통과해야하는 다른 모든 보안 검사와 함께 empty ()를 검사해야합니다. 외부 피드 나 라이브러리에서 오는 경우 try / catch로 래핑해야합니다. 데이터베이스에서 오는 경우 $ db_num_rows () 또는 이에 상응하는 것이 검사되어야합니다. 내부 변수에서 오는 경우 올바르게 초기화해야합니다. 이러한 유형의주의 사항은 종종 실패시 FALSE를 반환하는 함수 반환에 새 변수를 지정하는 것으로부터 발생합니다. 오류가 발생하면 변수를 허용 가능한 기본값으로 할당 할 수있는 테스트에 래핑해야합니다 코드에서 처리 할 수 있거나 코드가 처리 할 수있는 예외를 throw합니다. 이러한 것들은 코드를 더 길게 만들고, 여분의 블록을 추가하고, 추가 테스트를 추가하지만, 나는 그들이 여러분이 가장 가치있게 추가했다고 생각한다는 점에서 동의하지 않습니다.
가독성에 대한 정의가 무엇인지 모르겠지만 empty (), isset () 및 try / throw / catch 블록을 올바르게 사용하는 것이 전체 프로세스에서 매우 중요합니다. E_NOTICE가 $ _GET 또는 $ _POST에서 오는 경우, 그 데이터가 통과해야하는 다른 모든 보안 검사와 함께 empty ()를 검사해야합니다. 외부 피드 나 라이브러리에서 오는 경우 try / catch로 래핑해야합니다. 데이터베이스에서 오는 경우 $ db_num_rows () 또는 이에 상응하는 것이 검사되어야합니다. 내부 변수에서 오는 경우 올바르게 초기화해야합니다. 이러한 유형의주의 사항은 종종 실패시 FALSE를 반환하는 함수 반환에 새 변수를 지정하는 것으로부터 발생합니다. 오류가 발생하면 변수를 허용 가능한 기본값으로 할당 할 수있는 테스트에 래핑해야합니다 코드에서 처리 할 수 있거나 코드가 처리 할 수있는 예외를 throw합니다. 이러한 것들은 코드를 더 길게 만들고, 여분의 블록을 추가하고, 추가 테스트를 추가하지만, 나는 그들이 여러분이 가장 가치있게 추가했다고 생각한다는 점에서 동의하지 않습니다.
-
==============================
10.소프트웨어는 신의 은혜로 마술처럼 움직이지 않습니다. 당신이 놓친 것을 기대하고 있다면 제대로 처리해야합니다. 이를 무시하면 응용 프로그램에 보안 허점이 생길 수 있습니다. 정의되지 않은 변수에 액세스하는 정적 언어는 단지 불가능합니다. null 인 경우 응용 프로그램을 컴파일하거나 크래시하지 않습니다. 또한 응용 프로그램을 유지할 수 없게 만들고 예기치 않은 일이 발생하면 화를 낼 것입니다. 언어의 엄격함은 필수이고 PHP는 설계 상 많은면에서 잘못되었습니다. 당신이 잘 모르는 경우 나쁜 프로그래머가 될 것입니다.
소프트웨어는 신의 은혜로 마술처럼 움직이지 않습니다. 당신이 놓친 것을 기대하고 있다면 제대로 처리해야합니다. 이를 무시하면 응용 프로그램에 보안 허점이 생길 수 있습니다. 정의되지 않은 변수에 액세스하는 정적 언어는 단지 불가능합니다. null 인 경우 응용 프로그램을 컴파일하거나 크래시하지 않습니다. 또한 응용 프로그램을 유지할 수 없게 만들고 예기치 않은 일이 발생하면 화를 낼 것입니다. 언어의 엄격함은 필수이고 PHP는 설계 상 많은면에서 잘못되었습니다. 당신이 잘 모르는 경우 나쁜 프로그래머가 될 것입니다.
-
==============================
11.@ 연산자를 사용하는 것은 어떻습니까? 예 :
@ 연산자를 사용하는 것은 어떻습니까? 예 :
if(@$foo) { /* do something */ }
$ foo 내부에서 어떤 일이 일어나는지 제어 할 수 없기 때문에 (예를 들어 PHP 오류가 포함 된 함수 호출 인 경우)이 방법을 변수에만 사용하면이 방법은 다음과 동일합니다.
if(isset($foo) && $foo) { /* ... */ }
from https://stackoverflow.com/questions/1960509/how-to-avoid-isset-and-empty by cc-by-sa and MIT license
'PHP' 카테고리의 다른 글
양식을 제출 한 후 백그라운드에서 PHP 스크립트를 실행하려면 어떻게해야합니까? (0) | 2018.09.20 |
---|---|
PHP $ _SERVER [ 'HTTP_HOST'] 대 $ _SERVER [ 'SERVER_NAME'], 맨 페이지를 제대로 이해하고 있습니까? (0) | 2018.09.20 |
PHP에서 언어 구성과 "내장"기능의 차이점은 무엇입니까? (0) | 2018.09.20 |
어떤 $ _SERVER 변수가 안전합니까? (0) | 2018.09.20 |
ToString () PHP에서 이에 상응하는 (0) | 2018.09.20 |