Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHP - tips & tricks

3a453374a79becf33b3a6659389a56c4?s=47 Radek Benkel
December 18, 2011

PHP - tips & tricks

Tips and tricks about PHP - some rechniques, not well known functions etc.

3a453374a79becf33b3a6659389a56c4?s=128

Radek Benkel

December 18, 2011
Tweet

More Decks by Radek Benkel

Other Decks in Technology

Transcript

  1. PHP TIPS & TRICKS 1

  2. PHP TIPS & TRICKS 2 AKA JOURNEY INTO DEPTHS OF

    MANUAL
  3. 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 ;]
  4. DEVELOPERS OFFEN WRITE FUNCTIONS FOR SOMETHING, THAT ALREADY EXISTS. 4

  5. WHY? 5

  6. WHY? SOMETIMES THEY WANT TO DO SOMETHING BETTER. 6

  7. WHY? SOMETIMES THEY WANT TO DO SOMETHING BETTER. OR JUST

    DON'T KNOW THAT SOMETHING ALREADY EXISTS. 7
  8. SOME OF THESE YOU MAY KNOW. 8

  9. SOME OF THESE YOU MAY KNOW. SOME DON'T. 9

  10. SOME OF THESE YOU MAY KNOW. SOME DON'T. IF YOU

    KNOW BETTER SOLUTION, PLEASE SHARE :) 10
  11. SHORT TERNARY OPERATOR 11

  12. SHORT TERNARY OPERATOR 12 $var = 'SomeValue'; $output = $var

    ? $var : 'default'; $output = $var ?: 'default'; //PHP >= 5.3
  13. DIRECTORY LISTING 13

  14. 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); } }
  15. DIRECTORY LISTING #2 15 $dir = "/application/modules/*"; foreach(glob($dir) as $file)

    { echo "Filename is: " . $file . PHP_EOL; }
  16. DIRECTORY LISTING #3 16 $dir = "/application/modules/"; foreach (new DirectoryIterator($dir)

    as $fileInfo) { echo "Filename is: " . $fileInfo->getFilename() . PHP_EOL; }
  17. DIRECTORY LISTING #3 17 $dir = "/application/modules/"; foreach (new DirectoryIterator($dir)

    as $fileInfo) { echo "Filename is: " . $fileInfo->getFilename() . PHP_EOL; } and
  18. EXPLODED STRING VALUES 18

  19. 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];
  20. FILEPATH INFORMATION 20

  21. 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];
  22. FILEPATH INFORMATION 22 But

  23. 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);
  24. FIRST NOT EMPTY VARIABLE 24

  25. FIRST NOT EMPTY VARIABLE 25 AKA COALESCE, NVL

  26. FIRST NOT EMPTY VARIABLE 26 $a = null; $b =

    false; $c = 14; $d = 'foo'; $notEmpty = $a ?: $b ?: $c ?: $d; echo $notEmpty // 14
  27. DEEP VAR INTERPOLATION 27

  28. 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 in echo "Value is $obj->foo->bar"; //Value is 123 echo "Value is {$obj->foo->bar}"; //Same for array $ar = array('some' => 'var'); echo "Value is $ar['some']"; //syntax error echo "Value is {$ar['some']}"; //Value is var
  29. MULTIPLE ISSET 29

  30. MULTIPLE ISSET 30 $val = null; $var = true; if

    (isset($not_defined) && isset($val) && isset($var)) { /* ... */ }
  31. MULTIPLE ISSET 31 if (isset($not_defined) && isset($val) && isset($var)) {

    /* ... */ } if (isset($not_defined, $val, $var)) { /* ... */ } ===
  32. FILTER_INPUT 32

  33. FILTER_INPUT 33 $action = isset($_POST['action']) ? some_validate($_POST['action']) : 'default_action';

  34. FILTER_INPUT 34

  35. 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);
  36. STRING CONCATENATION 36

  37. STRING CONCATENATION 37 TIME

  38. STRING CONCATENATION 38 WHO

  39. STRING CONCATENATION 39 WHO

  40. STRING CONCATENATION 40 CORRECT!

  41. STRING CONCATENATION 41

  42. 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...
  43. 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...
  44. 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...
  45. STRING CONCATENATION 45 WHY

  46. STRING CONCATENATION 46 STRING PATTERN REUSE (CONNECTION STRINGS, API CALLS,

    ETC.)
  47. STRING CONCATENATION 47 LOT OF FORMATTING OPTIONS

  48. QUICK OBJECT DEFINITION 48

  49. 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}
  50. ENUM 50

  51. 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) }*/
  52. SPL FTW! 52

  53. DATE/TIME MANIPULATION 53

  54. DATE/TIME MANIPULATION 54

  55. DATE/TIME MANIPULATION 55 + OBJECT/PROCEDURAL + TIMEZONES + INTERVALS +

    SOME OPERATORS + PHP CORE SINCE 5.2
  56. 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)); // false var_dump(($a > $b)); // true var_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');
  57. "DID YOU MEAN ..." 57

  58. "DID YOU MEAN ..." 58

  59. "DID YOU MEAN ..." 59 http://php.net/manual/en/ function.levenshtein.php YOU CAN TRY:

  60. PARSING URL PARAMS 60

  61. PARSING URL PARAMS 61 parse_url + parse_str

  62. 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 */
  63. 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 ) */
  64. 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
  65. PARSING URL PARAMS 65 parse_str function foo() { parse_str('single=Single&check[]=check1&check[]=foo&radio=radio2'); print_r(get_defined_vars());die();

    } foo(); Local
  66. CSV PARSING 66

  67. CSV PARSING 67 fgetcsv + str_getcsv

  68. 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); } ?>
  69. 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 );
  70. AUTO_PREPEND_FILE 70

  71. AUTO_PREPEND_FILE 71 php.ini auto_prepend_file string Specifies 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.
  72. AUTO_PREPEND_FILE 72 php.ini auto_prepend_file string Specifies 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
  73. FILE INCLUDE 73

  74. FILE INCLUDE 74 //config.php $dbName = 'some'; $dbPass = 'foo';

    $dpPort = 123; //index.php include 'config.php'; echo $dbPass; //echo 'some'
  75. FILE INCLUDE 75 //config.php $dbName = 'some'; $dbPass = 'foo';

    $dpPort = 123; //index.php include 'config.php'; echo $dbPass; //echo 'some' Local
  76. FILE INCLUDE 76 //config.php return array( 'dbName' => 'some', 'dbPass'

    => 'foo', 'dbPort' => 123 ); //index.php $config = include 'config.php'; echo $dbPass; //Notice 'undefined' echo $config['dbName'] = 'some';
  77. FILE INCLUDE 77 //function.php return function($data) { print_r($data);die(); }; //index.php

    $dump = include 'function.php'; $dump(array("hello", 'moto')); BTW.
  78. QUICK COMMENT WITHOUT IDE 78

  79. QUICK COMMENT 79 function foo() { $items = array(); foreach

    (array('some', 'a') as $item) { if ($item === 'a') { continue; } $items[] = $item; } return $items; }
  80. QUICK COMMENT 80 function foo() { $items = array(); /*

    foreach (array('some', 'a') as $item) { if ($item === 'a') { continue; } $items[] = $item; } */ return $items; }
  81. QUICK COMMENT 81 function foo() { $items = array(); /*

    */ foreach (array('some', 'a') as $item) { if ($item === 'a') { continue; } $items[] = $item; } /* */ return $items; }
  82. QUICK COMMENT 82 function foo() { $items = array(); /*

    * foreach (array('some', 'a') as $item) { if ($item === 'a') { continue; } $items[] = $item; } /* */ return $items; }
  83. QUICK COMMENT 83 function foo() { $items = array(); /*

    * foreach (array('some', 'a') as $item) { if ($item === 'a') { continue; } $items[] = $item; } /* */ return $items; } Another
  84. ONE LINE VARIABLE SWAP 84

  85. ONE LINE VARIABLE SWAP 85 $a = 123; $b =

    987; list($a, $b) = array($b, $a); echo $a; //987 echo $b; //123 //or $a ^= $b ^= $a ^= $b; //http://betterexplained.com/articles/swap-two-variables-using-xor/
  86. COMPACT + EXTRACT 86

  87. 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')); }
  88. COMPACT + EXTRACT 88 function foo() { $data = array('some'

    => 'asa', 'foo' => 'asda'); extract($data); var_dump(get_defined_vars());die(); } foo();
  89. COMPACT + EXTRACT 89 function foo() { $data = array('some'

    => 'asa', 'foo' => 'asda'); extract($data); var_dump(get_defined_vars());die(); } foo(); Once
  90. FIRST ARRAY ELEMENT WITH ASSOCIATIVE KEYS 90

  91. FIRST ARRAY ELEMENT 91 $data = array( 'foo' => 123,

    'bar' => 1987, 'wee' => 'ugh' ); //echo $data[0]; //undefined offset echo reset($data); //123 echo 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
  92. RANDOM ARRAY ITEM 92

  93. 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)];
  94. MULTIPLE VALUE CHECK 94

  95. 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'; }
  96. 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'; }
  97. 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'; }
  98. MULTIPLE VALUE CHECK 98 in_array($needle, $haystack) works like '==' in_array($needle,

    $haystack, true) works like '===' BTW!
  99. 99 EMPTY ARRAY CHECK

  100. EMPTY ARRAY CHECK 100 $input = array(); //it will work

    if (is_array($input) && count($input) === 0) { } //via @wookiebpl if ($input === array()) { }
  101. EMPTY ARRAY CHECK 101 //why not '=='? if ($input ==

    array()) { }
  102. EMPTY ARRAY CHECK 102 http://php.net/manual/en/types.comparisons.php

  103. 103 INNER ARRAYS OPERATIONS

  104. INNER ARRAYS OPERATIONS 104 $shopCartPrices = array( 1 => 123.12,

    4 => 23.34, 6 => 99.23 ); //sum? basic stuff. $sum = array_sum($shopCartPrices);
  105. INNER ARRAYS OPERATIONS 105 BUT SOMETIMES...

  106. INNER ARRAYS OPERATIONS 106

  107. INNER ARRAYS OPERATIONS 107

  108. 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']; }
  109. 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));
  110. INNER ARRAYS OPERATIONS 110 BUT

  111. INNER ARRAYS OPERATIONS 111 OR

  112. 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. 113 LAST

  114. 114 $var = 'a'; for($i = 0; $i < 150;

    $i++) { $var++; echo $var, ' '; } //output?
  115. 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. 116 IT'S

  117. 117