php tips & tricks
Post on 06-May-2015
15.199 Views
Preview:
DESCRIPTION
TRANSCRIPT
PHP TIPS & TRICKS
1
PHP TIPS & TRICKS
2
AKAJOURNEY INTO DEPTHS OF MANUAL
3
name: Radosław Benkel
nick: singles
www: http://www.rbenkel.me
twitter: @singlespl *
* and I have nothing in common with http://www.singles.pl ;]
DEVELOPERS OFFEN WRITE FUNCTIONS FOR
SOMETHING, THAT ALREADY EXISTS.
4
WHY?
5
WHY?
SOMETIMES THEY WANT TO DO SOMETHING BETTER.
6
WHY?
SOMETIMES THEY WANT TO DO SOMETHING BETTER.
OR JUST DON'T KNOW THAT SOMETHING ALREADY
EXISTS.7
SOME OF THESE YOU MAY KNOW.
8
SOME OF THESE YOU MAY KNOW.
SOME DON'T.
9
SOME OF THESE YOU MAY KNOW.
SOME DON'T.
IF YOU KNOW BETTER SOLUTION, PLEASE SHARE :)
10
SHORT TERNARY OPERATOR
11
SHORT TERNARY OPERATOR
12
$var = 'SomeValue';
$output = $var ? $var : 'default';
$output = $var ?: 'default'; //PHP >= 5.3
DIRECTORY LISTING
13
DIRECTORY LISTING #1
14
$dir = "/application/modules/*";if (is_dir($dir)) { if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { echo "Filename is: " . $file . PHP_EOL; } closedir($dh); }}
DIRECTORY LISTING #2
15
$dir = "/application/modules/*";foreach(glob($dir) as $file) { echo "Filename is: " . $file . PHP_EOL;}
DIRECTORY LISTING #3
16
$dir = "/application/modules/";foreach (new DirectoryIterator($dir) as $fileInfo) { echo "Filename is: " . $fileInfo->getFilename() . PHP_EOL;}
DIRECTORY LISTING #3
17
$dir = "/application/modules/";foreach (new DirectoryIterator($dir) as $fileInfo) { echo "Filename is: " . $fileInfo->getFilename() . PHP_EOL;}
and����������� ������������������ lot����������� ������������������ of����������� ������������������ others:http://www.php.net/manual/en/class.directoryiterator.php
EXPLODED STRING VALUES
18
EXPLODED STRING VALUES
19
$string = 'bazinga.foo.bar.suitup!'
$values = explode('.', $string);$sheldon = $values[0]; //bazinga$barney = $values[3]: //suitup
list($sheldon, , , $barney) = explode('.', $string);
//PHP 5.4 stuff$sheldon = explode('.', $string)[0];$barney = explode('.', $string)[3];
FILEPATH INFORMATION
20
FILEPATH INFORMATION
21
$path = '/some/directory/in/filesystem/file.some.txt';$parts = explode('/', $path);$partsCopy = $parts;array_pop($partsCopy);
// '/some/directory/in/filesystem'$filePath = implode('/', $partsCopy); $fileExtension = explode('.', $parts[count($parts) - 1]);
// 'txt'$fileExtension = $fileExtension[count($fileExtension)-1];
FILEPATH INFORMATION
22
But����������� ������������������ why?
FILEPATH INFORMATION
23
$path = '/some/directory/in/filesystem/file.some.txt';
$fileInfo = pathinfo($path); $fileInfo['dirname'] === pathinfo($path, PATHINFO_DIRNAME);$fileinfo['basename'] === pathinfo($path, PATHINFO_BASENAME);$fileinfo['extension'] === pathinfo($path, PATHINFO_EXTENSION);$fileinfo['filename'] === pathinfo($path, PATHINFO_FILENAME);
FIRST NOT EMPTY VARIABLE
24
FIRST NOT EMPTY VARIABLE
25
AKACOALESCE, NVL
FIRST NOT EMPTY VARIABLE
26
$a = null;$b = false;$c = 14;$d = 'foo'; $notEmpty = $a ?: $b ?: $c ?: $d;echo $notEmpty // 14
DEEP VAR INTERPOLATION
27
DEEP VAR INTERPOLATION
28
$obj = new stdClass();$obj->some = 'hello';$obj->foo = new stdClass();$obj->foo->bar = 123;
echo "Value is $obj->some";
//Object of class stdClass could not be converted to string inecho "Value is $obj->foo->bar"; //Value is 123echo "Value is {$obj->foo->bar}";
//Same for array$ar = array('some' => 'var');echo "Value is $ar['some']"; //syntax errorecho "Value is {$ar['some']}"; //Value is var
MULTIPLE ISSET
29
MULTIPLE ISSET
30
$val = null;$var = true;
if (isset($not_defined) && isset($val) && isset($var)) { /* ... */}
MULTIPLE ISSET
31
if (isset($not_defined) && isset($val) && isset($var)) { /* ... */}
if (isset($not_defined, $val, $var)) { /* ... */ }
===
FILTER_INPUT
32
FILTER_INPUT
33
$action = isset($_POST['action']) ? some_validate($_POST['action']) : 'default_action';
FILTER_INPUT
34
FILTER_INPUT
35
/* data actually came from POST$_POST = array( 'product_id' => 'libgd<script>', 'component' => '10', 'versions' => '2.0.33', 'testscalar' => array('2', '23', '10', '12'), 'testarray' => '2',);*/$args = array( 'product_id' => FILTER_SANITIZE_ENCODED, 'component' => array( 'filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_ARRAY, 'options' => array('min_range' => 1, 'max_range' => 10) ), 'versions' => FILTER_SANITIZE_ENCODED, 'doesnotexist' => FILTER_VALIDATE_INT, 'testscalar' => array( 'filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_SCALAR, ), 'testarray' => array( 'filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_ARRAY, ));$myinputs = filter_input_array(INPUT_POST, $args);
STRING CONCATENATION
36
STRING CONCATENATION
37
TIME����������� ������������������ FOR����������� ������������������ RIDDLE!
STRING CONCATENATION
38
WHO����������� ������������������ KNOWS����������� ������������������ WHAT'S����������� ������������������ THAT?
STRING CONCATENATION
39
WHO����������� ������������������ KNOWS����������� ������������������ WHAT'S����������� ������������������ THAT?
STRING CONCATENATION
40
CORRECT!
STRING CONCATENATION
41
STRING CONCATENATION
42
$a = 'scissors';$b = 'paper';$c = 'rock';$d = 'lizard';$e = 'Spock';
$rules = $a . ' cut ' . $b . ', ' . $b . ' covers ' . $c . ', ' . $c . ' crushes ' . $d . ', ' . $d . ' poisons ' . $e . '...'; echo $rules;//scissors cut paper, paper covers rock, rock crushes lizard, lizard poisons Spock...
STRING CONCATENATION
43
$a = 'scissors';$b = 'paper';$c = 'rock';$d = 'lizard';$e = 'Spock';
$rules = "$a cut $b, $b covers $c, $c crushes $d, $d poisons $e...";echo $rules;//scissors cut paper, paper covers rock, rock crushes lizard, lizard poisons Spock...
STRING CONCATENATION
44
$a = 'scissors';$b = 'paper';$c = 'rock';$d = 'lizard';$e = 'Spock';
$rules = "%s cut %s, %s covers %s, %s crushes %s, %s poisons %s...";echo sprintf($rules, $a, $b, $b, $c, $c, $d, $d, $e);echo vsprintf($rules, array($a, $b, $b, $c, $c, $d, $d, $e));printf($rules, $a, $b, $b, $c, $c, $d, $d, $e);vprintf($rules, array($a, $b, $b, $c, $c, $d, $d, $e));//4x scissors cut paper, paper covers rock, rock crushes lizard, lizard poisons Spock...
STRING CONCATENATION
45
WHY����������� ������������������ USE����������� ������������������ PRINTF����������� ������������������ FAMILY����������� ������������������ FUNCTIONS,����������� ������������������
WHEN����������� ������������������ WE����������� ������������������ HAVE����������� ������������������ STRING����������� ������������������ INTERPOLATION?
STRING CONCATENATION
46
STRING PATTERN REUSE (CONNECTION STRINGS, API CALLS,
ETC.)
STRING CONCATENATION
47
LOT OF FORMATTING OPTIONS
QUICK OBJECT DEFINITION
48
QUICK OBJECT DEFINITION
49
$obj = new stdClass();$obj->foo = 123;$obj->bar = 'some';
//or (btw. not recursive!)$obj = (object)array('foo' => 123, 'bar' => 'some');
// unfortunately - not possible :($obj = {'foo' => 123}
ENUM
50
ENUM
51
class Roles { const ADMIN = 1; const USER = 2; const GUEST = 3;}
$class = new ReflectionClass('Roles');var_dump($class->getConstants());
/*array(3) { ["ADMIN"]=> int(1) ["USER"]=> int(2) ["GUEST"]=> int(3)}*/
SPL FTW!
52
DATE/TIME MANIPULATION
53
DATE/TIME MANIPULATION
54
DATE/TIME MANIPULATION
55
+ OBJECT/PROCEDURAL+ TIMEZONES+ INTERVALS+ SOME OPERATORS+ PHP CORE SINCE 5.2
DATE/TIME MANIPULATION
56
$a = new DateTime('2011-12-12');$b = new DateTime('2011-11-12');$c = new DateTime('2011-12-12');
var_dump(($a < $b)); // falsevar_dump(($a > $b)); // truevar_dump(($c == $a)); // true
// works$a->add(new DateInterval('P2D'));echo $a->format('Y-m-d') // echo 2011-12-14
// dont work :($a += new DateInterval('P2D');
"DID YOU MEAN ..."
57
"DID YOU MEAN ..."
58
"DID YOU MEAN ..."
59
http://php.net/manual/en/function.levenshtein.php
YOU CAN TRY:
PARSING URL PARAMS
60
PARSING URL PARAMS
61
parse_url + parse_str
PARSING URL PARAMS
62
parse_url
$url = 'http://username:password@hostname/path?arg=value#anchor';print_r(parse_url($url));echo parse_url($url, PHP_URL_PATH); //and others, same as pathinfo/*Array( [scheme] => http [host] => hostname [user] => username [pass] => password [path] => /path [query] => arg=value [fragment] => anchor)/path*/
PARSING URL PARAMS
63
parse_str
parse_str('single=Single&check[]=check1&check[]=foo&radio=radio2', $data);print_r($data);die();
/*Array( [single] => Single [check] => Array ( [0] => check1 [1] => foo )
[radio] => radio2)*/
PARSING URL PARAMS
64
parse_str
parse_str('single=Single&check[]=check1&check[]=foo&radio=radio2', $data);print_r($data);die();
/*Array( [single] => Single [check] => Array ( [0] => check1 [1] => foo )
[radio] => radio2)*/
DOn't����������� ������������������ use����������� ������������������ without����������� ������������������ second����������� ������������������ parameter!
PARSING URL PARAMS
65
parse_strfunction foo() { parse_str('single=Single&check[]=check1&check[]=foo&radio=radio2'); print_r(get_defined_vars());die();}foo();
Local����������� ������������������ "magic"����������� ������������������ variables!
CSV PARSING
66
CSV PARSING
67
fgetcsv + str_getcsv
CSV PARSING
68
fgetcsv (for big files)
$row = 1;if (($handle = fopen("test.csv", "r")) !== FALSE) { while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $num = count($data); echo "<p> $num fields in line $row: <br /></p>\n"; $row++; for ($c=0; $c < $num; $c++) { echo $data[$c] . "<br />\n"; } } fclose($handle);}?>
CSV PARSING
69
str_getcsv (for smaller ones)
$line = 'AddDescription "My description to the file." filename.jpg';$parsed = str_getcsv( $line, # Input line ' ', # Delimiter '"', # Enclosure '\\' # Escape char);var_dump( $parsed );
AUTO_PREPEND_FILE
70
AUTO_PREPEND_FILE
71
php.ini
auto_prepend_file stringSpecifies the name of a file that is automatically parsed before the main file. The file is included as if it was called with the require()function, so include_path is used.
The special value none disables auto-prepending.
AUTO_PREPEND_FILE
72
php.ini
auto_prepend_file stringSpecifies the name of a file that is automatically parsed before the main file. The file is included as if it was called with the require()function, so include_path is used.
The special value none disables auto-prepending.
Great����������� ������������������ place����������� ������������������ for����������� ������������������ your����������� ������������������ awesome����������� ������������������ "mydie",����������� ������������������ "dump",����������� ������������������ "debug",����������� ������������������ "puke"����������� ������������������ etc.����������� ������������������ functions.����������� ������������������ But����������� ������������������ be����������� ������������������ careful����������� ������������������ when����������� ������������������ deploying.
FILE INCLUDE
73
FILE INCLUDE
74
//config.php$dbName = 'some';$dbPass = 'foo';$dpPort = 123;
//index.phpinclude 'config.php';echo $dbPass; //echo 'some'
FILE INCLUDE
75
//config.php$dbName = 'some';$dbPass = 'foo';$dpPort = 123;
//index.phpinclude 'config.php';echo $dbPass; //echo 'some'
Local����������� ������������������ "magic"����������� ������������������ variable!
FILE INCLUDE
76
//config.phpreturn array( 'dbName' => 'some', 'dbPass' => 'foo', 'dbPort' => 123);
//index.php$config = include 'config.php';echo $dbPass; //Notice 'undefined'echo $config['dbName'] = 'some';
FILE INCLUDE
77
//function.phpreturn function($data) { print_r($data);die();};
//index.php$dump = include 'function.php';$dump(array("hello", 'moto'));
BTW.����������� ������������������ THIS����������� ������������������ ALSO����������� ������������������ WORKS
QUICK COMMENT WITHOUT IDE
78
QUICK COMMENT
79
function foo() { $items = array(); foreach (array('some', 'a') as $item) { if ($item === 'a') { continue; } $items[] = $item; } return $items;}
QUICK COMMENT
80
function foo() { $items = array(); /* foreach (array('some', 'a') as $item) { if ($item === 'a') { continue; } $items[] = $item; } */ return $items;}
QUICK COMMENT
81
function foo() { $items = array(); /* */ foreach (array('some', 'a') as $item) { if ($item === 'a') { continue; } $items[] = $item; } /* */ return $items;}
QUICK COMMENT
82
function foo() { $items = array(); /* * foreach (array('some', 'a') as $item) { if ($item === 'a') { continue; } $items[] = $item; } /* */ return $items;}
QUICK COMMENT
83
function foo() { $items = array(); /* * foreach (array('some', 'a') as $item) { if ($item === 'a') { continue; } $items[] = $item; } /* */ return $items;}
Another����������� ������������������ options����������� ������������������ also����������� ������������������ possible
ONE LINE VARIABLE SWAP
84
ONE LINE VARIABLE SWAP
85
$a = 123;$b = 987;
list($a, $b) = array($b, $a);
echo $a; //987echo $b; //123
//or $a ^= $b ^= $a ^= $b;//http://betterexplained.com/articles/swap-two-variables-using-xor/
COMPACT + EXTRACT
86
COMPACT + EXTRACT
87
function index() { $user = Users::find(1); $items = Items::getAllForUser($user); return $this->render('index.twig', array( 'user' => $user, 'items' => $items ));
//same as return $this->render('index.twig', compact('user', 'items'));}
COMPACT + EXTRACT
88
function foo() { $data = array('some' => 'asa', 'foo' => 'asda'); extract($data); var_dump(get_defined_vars());die();}foo();
COMPACT + EXTRACT
89
function foo() { $data = array('some' => 'asa', 'foo' => 'asda'); extract($data); var_dump(get_defined_vars());die();}foo();
Once����������� ������������������ again����������� ������������������ local����������� ������������������ "magic"����������� ������������������ variables!
FIRST ARRAY ELEMENT WITH ASSOCIATIVE KEYS
90
FIRST ARRAY ELEMENT
91
$data = array( 'foo' => 123, 'bar' => 1987, 'wee' => 'ugh');
//echo $data[0]; //undefined offsetecho reset($data); //123echo current($data); //123
reset($data);list(,$value) = each($data);echo $value; //123
list($value) = array_values($data);echo $value; //123
echo array_shift($data); //123 - caution - modifies array//solution?echo array_shift(array_values($data)); //123 without modifying array
RANDOM ARRAY ITEM
92
RANDOM ARRAY ITEM
93
$data = array( 'foo' => 123, 'bar' => 1987, 'wee' => 'ugh');
// not like that - works only for number indexed arrays without gaps !$random = $data[rand(0, count($data) - 1)];// or that way - array_rand returns key, not value!$random = array_rand($data);
// that way - works always$random = $data[array_rand($data)];
MULTIPLE VALUE CHECK
94
MULTIPLE VALUE CHECK
95
$person = 'Barney';
if ($person == 'Joey' || $person == 'Rachel' || $person == 'Ross' || $person == 'Phoebe' || $person == 'Monica' || $person == 'Chandler') { echo 'Best comedy show ever';} else if ($person == 'Barney' || $person == 'Ted' || $person == 'Lily' || $person == 'Marshal' || $person == 'Robin') { echo 'Copy of best comedy show ever, but still good one';} else { echo 'Maybe another good show';}
MULTIPLE VALUE CHECK
96
$person = 'Barney';
switch ($person) { case 'Joey': case 'Rachel': case 'Ross': /* ... */ echo 'Best comedy show ever'; break; case 'Barney'; case 'Ted'; /* ... */ echo 'Like a copy of best show ever, but still good one'; break; default: echo 'Maybe another good show';}
MULTIPLE VALUE CHECK
97
$person = 'Barney';
if (in_array($person, array('Joey', 'Rachel', 'Ross', 'Phoebe', 'Monica', 'Chandler')))) { echo 'Best comedy show ever';} else if (in_array($person, array('Barney', 'Ted', 'Lily', 'Marshal', 'Robin')))) { echo 'Like a copy of best comedy show ever, but still good one';} else { echo 'Maybe another good show';}
MULTIPLE VALUE CHECK
98
in_array($needle, $haystack) works like '=='in_array($needle, $haystack, true) works like '==='
BTW!
99
EMPTY ARRAY CHECK
EMPTY ARRAY CHECK
100
$input = array();
//it will workif (is_array($input) && count($input) === 0) { }
//via @wookiebplif ($input === array()) { }
EMPTY ARRAY CHECK
101
//why not '=='?if ($input == array()) { }
EMPTY ARRAY CHECK
102
http://php.net/manual/en/types.comparisons.php
103
INNER ARRAYS OPERATIONS
INNER ARRAYS OPERATIONS
104
$shopCartPrices = array( 1 => 123.12, 4 => 23.34, 6 => 99.23);
//sum? basic stuff.$sum = array_sum($shopCartPrices);
INNER ARRAYS OPERATIONS
105
BUT SOMETIMES...
INNER ARRAYS OPERATIONS
106
INNER ARRAYS OPERATIONS
107
INNER ARRAYS OPERATIONS
108
$shopCartPrices = array( 1 => array( 'price' => 123.12 ), 4 => array( 'price' => 23.34 ), 6 => array( 'price' => 99.23 ));
//sure. you can do that$sum = 0;foreach ($shopCartPrices as $cartItem) { $sum += $cartItem['price'];}
INNER ARRAYS OPERATIONS
109
$shopCartPrices = array( 1 => array( 'price' => 123.12 ), 4 => array( 'price' => 23.34 ), 6 => array( 'price' => 99.23 ));
//but you can do better = PHP >= 5.3$sum = array_sum(array_map(function($cartItem) { return $cartItem['price'];}, $shopCartPrices));
INNER ARRAYS OPERATIONS
110
BUT����������� ������������������ WITH����������� ������������������ THIS����������� ������������������ ONE,����������� ������������������ PEOPLE����������� ������������������ OFTEN����������� ������������������ LOOK����������� ������������������ AT����������� ������������������ ME����������� ������������������ LIKE����������� ������������������ ����������� ������������������
SOMEONE����������� ������������������ WHO'S����������� ������������������ USING����������� ������������������ MAGIC.
INNER ARRAYS OPERATIONS
111
OR����������� ������������������ FORCE
INNER ARRAYS OPERATIONS
112
$shopCartPrices = array( 1 => array( 'price' => 123.12 ), 4 => array( 'price' => 23.34 ), 6 => array( 'price' => 99.23 ));
//and sometimes, even better - without PHP 5.3$sum = array_sum(array_map('array_pop', $shopCartPrices));
113
LAST����������� ������������������ RIDDLE
114
$var = 'a';for($i = 0; $i < 150; $i++) { $var++; echo $var, ' ';}
//output?
115
$var = 'a';for($i = 0; $i < 150; $i++) { $var++; echo $var, ' ';}
//output?
//b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb bc bd be bf bg bh bi bj bk bl bm bn bo bp bq br bs bt bu bv bw bx by bz ca cb cc cd ce cf cg ch ci cj ck cl cm cn co cp cq cr cs ct cu cv cw cx cy cz da db dc dd de df dg dh di dj dk dl dm dn do dp dq dr ds dt du dv dw dx dy dz ea eb ec ed ee ef eg eh ei ej ek el em en eo ep eq er es et eu
116
IT'S����������� ������������������ NOT����������� ������������������ A����������� ������������������ BUG.����������� ������������������ IT'S����������� ������������������ A����������� ������������������ FEATURE����������� ������������������ :]
117
top related