SlideShare a Scribd company logo
1 of 70
Download to read offline
UNSUNG HEROES OF PHP
                                 JAKE SMITH




http://joind.in/talk/view/2971
Jake Smith
[t] @jakefolio
[w] http://jakefolio.com
[e] me@jakefolio.com
Clean Your Inputs
   with filter_var();
filter_var/filter_input


              • Available since PHP 5.2.x
              • Validate or Sanitize variable/input
              • Input = GET, POST, ENV, COOKIE,
                    SERVER

                   • The input can not be manipulated

Source: http://www.php.net/manual/en/filter.filters.php
filter_input/filter_has_var
Can not add additional fields to filter_input
if ($_POST) {
  $_POST['additional_field'] = "valid string";

    $result = filter_input(INPUT_POST, 'additional_field', FILTER_SANITIZE_STRING); // false
    $result2 = filter_has_var(INPUT_POST, 'additional_field'); // false
}
Filter - Email



              • FILTER_VALIDATE_EMAIL
              • FILTER_SANITIZE_EMAIL
               • Strip all non-email characters
              • Email standards based on RFC 822

Source: http://www.faqs.org/rfcs/rfc822.html
Filter - email
Official RFC822 regular expression
(?:(?:rn)?[ t])*(?:(?:(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?
[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:
[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[
["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|
Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*|(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()
<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)*<(?:(?:rn)?[ t])*(?:@(?:[^()<>@,;:".[] 000-031]+(?:(?:
(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-
031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*(?:,@(?:(?:rn)?[ t])*(?:[^()<>@,;:".
[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()
<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["(<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*)*:(?:(?:rn)?[ t])
*)?(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?
[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:r
n)?[ t]))*"(?(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|
[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".
[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*>(?:(?:rn)?[ t])*)|(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()
<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)*:(?:(?:rn)?[ t])*(?:(?:(?:[^()<>@,;:".[] 000-031]+(?:(?:
(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:
".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:r
n)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.
(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?
[ t])*))*|(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:r
n)?[ t])*)*<(?:(?:rn)?[ t])*(?:@(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*
](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r
]|.)*](?:(?:rn)?[ t])*))*(?:,@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|
[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".
[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*)*:(?:(?:rn)?[ t])*)?(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()
<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:
rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".
[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()
<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*>(?:(?:rn)?[ t])
*)(?:,s*(?:(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:
rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|
(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".
[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()
<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*|(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".
[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)*<(?:(?:rn)?[ t])*(?:@(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?
[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:
(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*(?:,@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-
031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".
[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*)*:(?:(?:rn)?[ t])*)?(?:[^()
<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.
(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))
*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r
]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|
[([^[]r]|.)*](?:(?:rn)?[ t])*))*>(?:(?:rn)?[ t])*))*)?;s*)
Filter - email
Validate email examples: returns string if valid and false on failure
if (preg_match('/^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4})$/', $email)) {
  echo "Email Good";
}

// test good email address
echo filter_var("chris@example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Good

// test good email address
echo filter_var("chris@a.b.c.example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Good

// not allowed . before @
echo filter_var("chris.@example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad

// not allowed .. in domain part
echo filter_var("chris@example..com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad

// not allowed . after @
echo filter_var("chris@.example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad

// not allowed double @
echo filter_var("chris@@example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad

// not allowed @ more than once anywhere
echo filter_var("chris@exa@mple.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad

// must have @
echo filter_var("chris#example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad




Source: http://www.electrictoolbox.com/php-email-validation-filter-var/
Filter - URL


              • FILTER_VALIDATE_URL
              • FILTER_SANITIZE_URL
               • Strip all non-url characters
              • URL standards based on RFC 2396
                   •     Note that the function will only find ASCII URLs to be valid;
                         internationalized domain names (containing non-ASCII characters)
                         will fail.




Source: http://www.faqs.org/rfcs/rfc2396
Filter - url
URLS to be tested for validation
$urls = array(
    'http://www.lonestarphp.com',
    'http://www.lonestarphp.com',
    'http://www.lonestarphp.com/blog',
    'http://www.lonestarphp.com/index.html#anchor',
    'http://www.lonestarphp.com/index.html?q=123',
    'lonestarphp.com',
    'www.lonestarphp.com',
    'www.lonestarphp.com/blog',
    'www.lonestarphp.com/index.html?q=123',
    '/index.html?q=123',
    'https://www.lonestarphp.com/',
    'https://localhost',
    'https://localhost/',
    'https://127.0.0.1/',
    'http://.com',
    'http://...',
    'http://',
    'http://i'me really trying to break this url!!!"£$"%$&*()'
);
Filter - url
URLS validation combinations
foreach ($urls AS $i => $url) {
  $result[$i]['base'] = filter_var($url, FILTER_VALIDATE_URL) ? 'PASS' : 'FAIL';

  $result[$i]['path_required'] = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED) ?
'PASS' : 'FAIL';

  $result[$i]['query_required'] = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED) ?
'PASS' : 'FAIL';

  $result[$i]['path_scheme_required'] = filter_var($url, FILTER_VALIDATE_URL,
FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_PATH_REQUIRED) ? 'PASS' : 'FAIL';
}
Filter - url
URLS validation results
Filter - String

• FILTER_SANITIZE_STRING
 • Strip tags
• Flags:
 •   FILTER_FLAG_NO_ENCODE_QUOTES

 •   FILTER_FLAG_STRIP_LOW / FILTER_FLAG_STRIP_HIGH

 •   FILTER_FLAG_ENCODE_LOW / FILTER_FLAG_ENCODE_HIGH

 •   FILTER_FLAG_ENCODE_AMP
Filter - string
Sanitize string utilizing different flags
$string = "<strong>tcafén</strong>";

// Removes HTML tags (acts like strip_tags())
echo filter_var($string, FILTER_SANITIZE_STRING) . "<br>";

// This will remove the tab, the line break and HTML tags
echo filter_var($string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);

// This will remove the é and HTML tags.
echo filter_var($string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
Filter - string
ASCII Table




Source: http://www.asciitable.com/
Filter - url
ASCII Extended Table




Source: http://www.asciitable.com/
Filter - Boolean



• FILTER_VALIDATE_BOOLEAN
 • returns true for: “yes”, 1, “on”, true
 • returns false for: “non”, 0, “off”, false
Filter - boolean
Sanitize string utilizing different flags
$data = array(
   'terms_of_service' => 'yes',
   'logged_in_user' => true,
   'forged_field' => 3523621,
   'opt_in' => 'no'
);

$result = filter_var_array($data, FILTER_VALIDATE_BOOLEAN);

var_dump($result);

foreach($result AS $key => $val) {
  if ($val === null) {
    echo $key . ' Can Not Validate <br>';
  }
  if ($val === false) {
    echo $key . ' Failed Validation <br>';
  }
}

/* OUTPUT
array(4) {
   ["terms_of_service"]=> bool(true)
   ["logged_in_user"]=> bool(true)
   ["forged_field"]=> bool(false)
   ["opt_in"]=> bool(false) }
*/
Filter - boolean
Apply filter and flag on each element
$result = filter_var_array($data, array(
  'terms_of_service' => array(
     'filter' => FILTER_VALIDATE_BOOLEAN,
     'flags' => FILTER_NULL_ON_FAILURE
  ),
  'logged_in_user' => array(
     'filter' => FILTER_VALIDATE_BOOLEAN,
     'flags' => FILTER_NULL_ON_FAILURE
  ),
  'forged_field' => array(
     'filter' => FILTER_VALIDATE_BOOLEAN,
     'flags' => FILTER_NULL_ON_FAILURE
  ),
  'opt_in' => array(
     'filter' => FILTER_VALIDATE_BOOLEAN,
     'flags' => FILTER_NULL_ON_FAILURE
  )
));

var_dump($result);

/* OUTPUT
array(4) {
   ["terms_of_service"]=> bool(true)
   ["logged_in_user"]=> bool(true)
   ["forged_field"]=> NULL
   ["opt_in"]=> bool(false) }
*/
Filter - boolean
Apply filter and flag to all elements with PHP 5.3 closure
$result = filter_var_array($data, array_map(function() {
     return array(
        'filter' => FILTER_VALIDATE_BOOLEAN,
        'flags' => FILTER_NULL_ON_FAILURE
     );
   }, $data)
);

var_dump($result);

/* OUTPUT
array(4) {
   ["terms_of_service"]=> bool(true)
   ["logged_in_user"]=> bool(true)
   ["forged_field"]=> NULL
   ["opt_in"]=> bool(false) }
*/
Filter - Integer



• FILTER_VALIDATE_INT
• FILTER_SANITIZE_INT
 • remove all characters except digits
    and +-
Filter - integer
Validate integer using extra options
$year = filter_var('2032', FILTER_VALIDATE_INT, array(
   'min_range' => 1927,
   'max_range' => 2011)
);
Filter - Float


• FILTER_VALIDATE_FLOAT
 • FILTER_FLAG_ALLOW_THOUSAND
• FILTER_SANITIZE_FLOAT
 • FILTER_FLAG_ALLOW_FRACTION
 • FILTER_FLAG_ALLOW_SCIENTIFIC
Filter - float
Show different types of validation/sanitization
// Removes the , even though it's a validate and not a sanitize
$totalDonation[] = filter_var('123,523.72', FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND);

// Fails because the ALLOW_THOUSAND flag is not set
$totalDonation[] = filter_var('123,523.72', FILTER_VALIDATE_FLOAT);

// No sanitization needed
$totalDonation[] = filter_var('123,523.72', FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_THOUSAND |
FILTER_FLAG_ALLOW_FRACTION);

// Removes ,
$totalDonation[] = filter_var('123,523.72', FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

$sciNotation = filter_var('2352e28', FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_SCIENTIFIC);

foreach($totalDonation AS $donation) {
  // Failed validation if false returned.
  if ($donation === false) {
    echo "FAILED VALIDATION";
  }
  echo $donation . "<br>";
}

echo $sciNotation;
Putting it all together!
filter_input_array
Basic Contact Form HTML
<form action="" method="post">
  <p>
    <label>First Name</label><br>
    <input type="text" name="first_name">
  </p>
  <p>
    <label>Last Name</label><br>
    <input type="text" name="last_name">
  </p>
  <p>
    <label>E-mail</label><br>
    <input type="email" name="email">
  </p>
  <p>
    <label>Cell Number</label><br>
    <input type="text" name="cell_phone">
  </p>
  <p>
    <label>Feedback</label><br>
    <textarea name="message">Please add feedback</textarea>
  </p>
  <p>
    <label>Disclaimer</label><br>
    <input type="checkbox" name="disclaimer" value="yes"> Check box for generic disclaimer
  </p>
  <p><input type="submit" value="Submit Form"></p>
</form>
filter_input_array
Basic Contact Form without filter_input_array
if ($_POST) {

    foreach($_POST AS $id => $val) {
      $_POST[$id] = strip_tags($val);
    }

    if (empty($_POST['first_name'])) {
      $errors[] = "First Name is a required field.";
    }

    if (empty($_POST['last_name'])) {
      $errors[] = "Last Name is a required field.";
    }

    if (!preg_match(
      '/^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4})$/',
       $_POST['email'])) {
      $errors[] = "Email is invalid.";
    }

    if (!isset($_POST['disclaimer']) || $_POST['disclaimer'] != 'yes') {
      $errors[] = "You must accept the disclaimer.";
    }
}
Filter - string
Basic Contact Form WITH filter_input_array
if ($_POST) {
  $results = filter_input_array(INPUT_POST, array(
    // Strip Tags
    'first_name' => FILTER_SANITIZE_STRING,

     // Strip Tags
     'last_name' => FILTER_SANITIZE_STRING,

     // Validate Email
     'email' => FILTER_VALIDATE_EMAIL,

     // Strip all non-numeric characters
     'cell_phone' => FILTER_SANITIZE_NUMBER_INT,

     // Strip Tags
     'message' => FILTER_SANITIZE_STRING,

      // Validate Boolean value, return null if can not evaluate to boolean
      'disclaimer' => array(
        'filter' => FILTER_VALIDATE_BOOLEAN,
        'flags' => FILTER_NULL_ON_FAILURE
      )
    ));
    // Set Errors
    foreach($results AS $id => $val) {
      if ($val === NULL || $val === false) {
        $errors[] = "{$id} is invalid.";
      }
    }
}
Breaking into
XML with PHP
XML Libraries



• SimpleXML
• DOMDocument
• XMLReader/Writer
XML Section
Data Feed (Compliments of BreweryDB.com)
$data = <<<XML
  <beers>
     <beer>
       <id>6204</id>
       <name>"My" Bock</name>
       <description>
       Amber, malty and not too heavy, all around favorite even for the drinkers of the yellow fizzy stuff
       </description>
       <brewery>1428</brewery>
       <created>2011-06-01T09:39:12+00:00</created>
       <updated/>
     </beer>
     <beer>
       <id>7219</id>
       <name>"Ptarmigan" Pilsner</name>
       <description>
       Ptarmigan Pilsner our GABF Silver Medal Winner is A traditional European Style Pilsner with a light hop aroma, smooth malt flavor
and a distinctively clean finish.
       </description>
       <brewery>64</brewery>
       <created>2011-02-25T05:40:25+00:00</created>
       <updated/>
     </beer>
     <beer>
       <id>7218</id>
       <name>"Wheeler" Wheat</name>
       <description>
       Wheeler Wheat is a light and refreshing beer to quench your thirst after a hard day of adventure seeking. An American-style wheat
beer with just a hint of orange peel and coriander, enjoy it with a slice of fruit if you like, we recommend a slice of orange!
       </description>
       <brewery>64</brewery>
       <created>2011-02-25T05:36:45+00:00</created>
       <updated/>
     </beer>
  </beers>
XML;
SimpleXML



              • Tree Parser
              • Really awesome for quick and dirty
                    reading

              • Xpath built-in

Source: http://us.php.net/manual/en/class.simplexmlelement.php
SimpleXML
Read XML string and inject node
//$xml = simplexml_load_file();
$xml = simplexml_load_string($data); // $xml = new SimpleXMLElement($data);
echo "Enjoy some {$xml->beer[0]->name} <br>";

$result = $xml->xpath('//beer[brewery=64]');
foreach($result AS $beer) {
  echo "Found a {$beer->name} <br>";
}

// Add my brew
$myBeer = $xml->addChild('beer');
$myBeer->addChild('id', 12252);
$myBeer->addChild('name', '512 Pecan Porter');
$myBeer->addChild('description', 'Delicious beer from Austin go try!');

$exportedXML = $xml->asXML(); // $xml->saveXML();




Source: http://us.php.net/manual/en/class.simplexmlelement.php
SimpleXML
Scrape Craigslist - Searching for “leather” under “furniture”
$html = new DOMDocument();
$html->loadHTML(file_get_contents('http://dallas.craigslist.org/search/fua?
query=leather&srchType=A&minAsk=&maxAsk='));

$xml = simplexml_import_dom($html);

$results = $xml->xpath('//p[@class="row"]');

foreach($results as $listing) {
  // Strip the " -" from the end of the title
  $title = substr($listing->a, 0, -2);
  // Get Image filename from HTML id
  $imagePath = substr(
     $listing->span[0]->attributes()->id,
     strpos($listing->span[0]->attributes()->id, ':')+1
  );

    echo   '<p>';
    echo   ($imagePath) ? '<img src="http://images.craigslist.org/' . $imagePath . '">' : '';
    echo   $title;
    echo   '</p>';
}




Source: http://us.php.net/manual/en/class.simplexmlelement.php
DOMDocument



             • Tree Parser
             • Great at importing HTML/XHTML
             • Great at modifying/injecting nodes
             • Xpath built-in

Source: http://us.php.net/domdocument
DOMDocument
Read XML string and inject node
$newBeer = <<<XML
  <beer>
     <id>3252</id>
     <name>512 Pecan Porter</name>
     <description>
       Delicious nutty beer.
     </description>
     <brewery>23</brewery>
     <created>2011-06-11T05:36:45+00:00</created>
     <updated/>
  </beer>
XML;


$xml = new DOMDocument();
$xml->loadXML($exportedXML);

// Show name of first beer in xml document (from root, no xpath query)
echo $xml->getElementsByTagName('beer')->item(0)->getElementsByTagName('name')->item(0)->nodeValue;

$xpath = new DOMXpath($xml);
$res = $xpath->query('//beer[1]/name');

// Show name of first beer in xml document (DOMXpath)
echo $res->item(0)->nodeValue;

$beerXML = new DOMDocument();
$beerXML->loadXML($newBeer);

$node = $xml->importNode($beerXML->documentElement, true);
$xml->appendChild($node);
// $xml->replaceChild();
// $xml->removeChild();
echo $xml->saveXML();
Source: http://us.php.net/domdocument
DOMDocument
Scrape Craigslist - Searching for “leather” under “furniture”
$html = new DOMDocument();
$html->loadHTML(file_get_contents('http://dallas.craigslist.org/search/fua?
query=leather&srchType=A&minAsk=&maxAsk='));

$xpath = new DOMXpath($html);
$result = $xpath->query('//p[@class="row"]');

foreach($result AS $listing) {
  $title = substr($listing->getElementsByTagName('a')->item(0)->nodeValue, 0, -2);
  $imagePath = $listing->getElementsByTagName('span')->item(0)->getAttribute('id');
  $imagePath = substr($imagePath, strpos($imagePath, ':')+1);

    echo   '<p>';
    echo   ($imagePath) ? '<img src="http://images.craigslist.org/' . $imagePath . '">' : '';
    echo   $title;
    echo   '</p>';
}




Source: http://us.php.net/domdocument
XMLReader/Writer


• Pull Parser
• Full Steam Ahead - only moves forward
• Great for large XML documents
• Reads/Writes line by line, small
  memory footprint
XMLReader
Iterate Feed
$reader = new XMLReader();
$reader->open("http://www.brewerydb.com/api/beers/?apikey={$apiKey}");
while($reader->read()) {
  if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == "beer") {
    echo "<p>";
  }
  if ($reader->nodeType == XMLReader::ELEMENT || $reader->nodeType == XMLReader::TEXT) {
    switch($reader->name) {
      case "id";
      case "name";
      case "brewery";
      case "description";
      case "created";
      case "updated";
        echo $reader->name . ": ";
        continue;
      break;

          default:
        }
        if ($reader->nodeType == XMLReader::TEXT && $reader->value) {
          echo $reader->value . "<br>";
        }

        if ($reader->nodeType == XMLReader::END_ELEMENT && $reader->name == "beer") {
          echo "</p>";
        }
    }
}


Source: http://us.php.net/manual/en/class.xmlreader.php
XMLWriter
Headers and Data
header("Content-Type: text/html/force-download");
header("Content-Disposition: attachment; filename=beers.xml");
$beerArray = array(
   0 => array(
      'id' => 12451,
      'name' => 'Shiner 102',
      'brewery' => 526,
      'description' => 'Lone Star Approved!',
      'created' => '2011-06-11T05:36:45+00:00'
   ),
   1 => array(
      'id' => 23551,
      'name' => '512 Pecan Porter',
      'brewery' => 126,
      'description' => 'A bit nutty',
      'created' => '2011-06-11T05:36:45+00:00'
   ),
   2 => array(
      'id' => 35351,
      'name' => 'Brooklyn Lager',
      'brewery' => 226,
      'description' => 'New York City?',
      'reviews' => array(
         0 => 'Great',
         1 => 'Good',
         2 => 'Above Average'
      ),
      'created' => '2011-06-11T05:36:45+00:00'
   ),
);

Source: http://us.php.net/manual/en/ref.xmlwriter.php
XMLWriter
Setup
class XMLRecursiveIteratorIterator extends RecursiveIteratorIterator {

  protected $xml;

  public function __construct($it, $flag = RecursiveIteratorIterator::SELF_FIRST, XMLWriter $xml)
  {
    parent::__construct($it, $flag);
    $this->xml = $xml;
  }

  public function endChildren()
  {
    $this->xml->endElement();
  }
}
$xml = new XMLWriter();
$xml->openURI('php://output');
$xml->startDocument('1.0', 'UTF-8');
$xml->setIndent(4);




Source: http://us.php.net/manual/en/ref.xmlwriter.php
XMLWriter
Iteration
foreach($beers AS $key => $value) {

  // If back to the top level create new beer
  if ($beers->getDepth() == 0) {
    $xml->startElement('beer');
    continue;
  }

  // Change current parent to reviews
  if ($key == "reviews") {
    $currentParent = "reviews";
  }

  // Check if current value is a review or not
  $current = (is_int($key) && $currentParent == "reviews") ? "review" : $key;

  $xml->startElement($current);

  // Don't end the element if it is the start of a child list
  if (!$beers->hasChildren()) {
    $xml->text($value);
    $xml->endElement();
  }
}
// Close all open tags
$xml->endDocument();




Source: http://us.php.net/manual/en/ref.xmlwriter.php
XML Recap - SimpleXML



• Great for reading XML
• Is Iterable (we’ll talk more on this)
• Is NOT the end all be all for XML
• Has xpath (tree traversing)
XML Recap - DOMDocument



• Great for manipulating XML
• Can properly load (X)HTML files
• Has xpath (tree traversing)
XML Recap - XMLReader/Writer


• Extremely fast
• Handles stream context for source
• Best used with large XML docs or
  streams

• Forward moving (pull)
1...Iterator
2...Iterator
3...Iterator
      floor();
What is an Iterator?


               “      An iterator is an object that enables a
                      programmer to traverse a container.
                      Various types of iterators are often
                      provided via a container's interface.
                                                            ”

Source: http://en.wikipedia.org/wiki/Iterator
Quotes in the Community



              “       PHP also have a lot of awesome features; at
                      least two of them are in my opinion largely
                      underused: Iterators and Streams.
                      Fabien Potencier (Lead Developer of Symfony Project)
                                                                                       ”

Source: http://fabien.potencier.org/article/44/php-iterators-and-streams-are-awesome
Iterator Interfaces


                   • Traversable
                   • Iterator
                   • RecursiveIterator
                   • Countable
                   • SeekableIterator
Source: http://www.php.net/manual/en/spl.iterators.php
Interface - Iterator

                                     Iterator extends Traversable {

                                     /* Methods */
                                     abstract public mixed current ( void )
                                     abstract public scalar key ( void )
                                     abstract public void next ( void )
                                     abstract public void rewind ( void )
                                     abstract public boolean valid ( void )

                                     }




Source: http://us.php.net/manual/en/class.iterator.php
Interface - RecursiveIterator
                               RecursiveIterator extends Iterator {

                               /* Methods */
                               public RecursiveIterator getChildren ( void )
                               public bool hasChildren ( void )

                               /* Inherited methods */
                               abstract public mixed Iterator::current ( void )
                               abstract public scalar Iterator::key ( void )
                               abstract public void Iterator::next ( void )
                               abstract public void Iterator::rewind ( void )
                               abstract public boolean Iterator::valid ( void )

                               }




Source: http://www.php.net/manual/en/spl.iterators.php
DIRECTORY ITERATORS
DirectoryIterator
Output directory content for Zend Framework
$it = new DirectoryIterator('lib/Zend');
foreach ($it AS $file) {
  echo $file->getFilename() . "<br>";
}

OUTPUT:
.
..
.DS_Store
Acl
Acl.php
Amf
Application
Application.php
Auth
Auth.php
Barcode
Barcode.php
Cache
Cache.php
Captcha
Cloud
CodeGenerator
Config
Config.php
Console
Controller
Crypt
Crypt.php
Currency
Currency.php
Date


Source: http://us.php.net/manual/en/class.directoryiterator.php
DirectoryIterator - SPLFileInfo
Methods available
$it = new DirectoryIterator('lib/Zend');
foreach ($it AS $file) {
  echo $file->getFilename() . "<br>";
}

OUTPUT:
  /* Methods available for $file
  public int getATime ( void )
  public string getBasename ([ string $suffix ] )
  public int getCTime ( void )
  public string getExtension ( void )
  public SplFileInfo getFileInfo ([ string $class_name ] )
  public string getFilename ( void )
  public int getGroup ( void )
  public int getInode ( void )
  public string getLinkTarget ( void )
  public int getMTime ( void )
  public int getOwner ( void )
  public string getPath ( void )
  public SplFileInfo getPathInfo ([ string $class_name ] )
  public string getPathname ( void )
  public int getPerms ( void )
  public string getRealPath ( void )
  public int getSize ( void )
  public string getType ( void )
  public bool isDir ( void )
  public bool isExecutable ( void )
  public bool isFile ( void )
  public bool isLink ( void )
  public bool isReadable ( void )
  public bool isWritable ( void )
  */


Source: http://us.php.net/manual/en/class.splfileinfo.php
FileSystemIterator (PHP 5.3.x)
Output directory content for Zend Framework
$it = new FileSystemIterator('lib/Zend');

foreach ($it AS $path => $file) {
  echo $path . " - " . $file->getFilename() . "<br>";
}

OUTPUT:
lib/Zend/.DS_Store - .DS_Store
lib/Zend/Acl - Acl
lib/Zend/Acl.php - Acl.php
lib/Zend/Amf - Amf
lib/Zend/Application - Application
lib/Zend/Application.php - Application.php
lib/Zend/Auth - Auth
lib/Zend/Auth.php - Auth.php
lib/Zend/Barcode - Barcode
lib/Zend/Barcode.php - Barcode.php
lib/Zend/Cache - Cache
lib/Zend/Cache.php - Cache.php
lib/Zend/Captcha - Captcha
lib/Zend/Cloud - Cloud
lib/Zend/CodeGenerator - CodeGenerator
lib/Zend/Config - Config
lib/Zend/Config.php - Config.php
lib/Zend/Console - Console




Source: http://us.php.net/manual/en/class.filesystemiterator.php
GlobIterator (PHP 5.3.x)
Output directory content for Zend Framework
$it = new GlobIterator('lib/Zend/*');

foreach ($it AS $path => $file) {
  echo $path . " - " . $file->getFilename() . "<br>";
}

OUTPUT:
lib/Zend/Acl - Acl
lib/Zend/Acl.php - Acl.php
lib/Zend/Amf - Amf
lib/Zend/Application - Application
lib/Zend/Application.php - Application.php
lib/Zend/Auth - Auth
lib/Zend/Auth.php - Auth.php
lib/Zend/Barcode - Barcode
lib/Zend/Barcode.php - Barcode.php
lib/Zend/Cache - Cache
lib/Zend/Cache.php - Cache.php
lib/Zend/Captcha - Captcha
lib/Zend/Cloud - Cloud
lib/Zend/CodeGenerator - CodeGenerator
lib/Zend/Config - Config
lib/Zend/Config.php - Config.php
lib/Zend/Console - Console




Source: http://us.php.net/manual/en/class.globiterator.php
RecursiveTreeIterator (PHP 5.3.x)
Output ASCII view of Directory Structure
$it = new RecursiveDirectoryIterator('lib/Zend');

foreach (new RecursiveTreeIterator($it) AS $file) {
  echo $file . "n";
}

OUTPUT:
|-lib/Zend/Acl
| |-lib/Zend/Acl/Assert
| | -lib/Zend/Acl/Assert/Interface.php
| |-lib/Zend/Acl/Exception.php
| |-lib/Zend/Acl/Resource
| | -lib/Zend/Acl/Resource/Interface.php
| |-lib/Zend/Acl/Resource.php
| |-lib/Zend/Acl/Role
| | |-lib/Zend/Acl/Role/Interface.php
| | |-lib/Zend/Acl/Role/Registry
| | | -lib/Zend/Acl/Role/Registry/Exception.php
| | -lib/Zend/Acl/Role/Registry.php
| -lib/Zend/Acl/Role.php
|-lib/Zend/Acl.php
|-lib/Zend/Amf
| |-lib/Zend/Amf/Adobe
| | |-lib/Zend/Amf/Adobe/Auth.php
| | |-lib/Zend/Amf/Adobe/DbInspector.php
| | -lib/Zend/Amf/Adobe/Introspector.php
| |-lib/Zend/Amf/Auth
| | -lib/Zend/Amf/Auth/Abstract.php
| |-lib/Zend/Amf/Constants.php
| |-lib/Zend/Amf/Exception.php




Source: http://us.php.net/manual/en/class.recursivetreeiterator.php
FILTER ITERATORS
Problem:
                     Need to view all files in a directory, but
                       it keeps returning Version Control
                              folders (.svn and .git).




Source: http://www.php.net/manual/en/spl.iterators.php
FilterIterator
Do not show Version Control folders
class NoVCSIterator extends FilterIterator
{
  public function accept()
  {
    $file = $this->getInnerIterator()->current();

        if ($file->isDir() && ($file->getFilename() == '.git' || $file->getFilename() == '.svn')) {
          return false;
        }

        return true;
    }
}
Problem:
                       I need to see all images that are over
                           5MB that have been uploaded.




Source: http://www.php.net/manual/en/spl.iterators.php
FilterIterator
Only show images greater than 5MB
class LargeImageFilter extends FilterIterator
{
  protected $safeImageTypes = array('jpg', 'gif', 'png');

    public function __construct(Iterator $it, $imageTypes)
    {
      parent::__construct($it);
      if (count($imageTypes) > 0) {
        $this->safeImageTypes = $imageTypes;
      }
    }

    public function accept()
    {
      $file = $this->getInnerIterator()->current();

        if (in_array($file->getExtension(), $this->safeImageTypes) && $file->getSize() > 5242880)

        return true;
    }
}

$dir = new DirectoryIterator(UPLOADS_PATH);

foreach(new LargeImageFilter($dir) AS $file) {
  echo $file->getFileName();
}
RegexIterator
Move integers from front to the back (example from php.net)
/*
* RegexIterator::MATCH
* RegexIterator::REPLACE
* RegexIterator::ALL_MATCHES
* RegexIterator::SPLIT
*/

$a = new ArrayIterator(array('test1', 'test2', 'test3'));

$it = new RegexIterator($a, '/^(test)(d+)/', RegexIterator::REPLACE);
$it->replacement = '$2:$1';

foreach($it AS $el) {
  echo $el;
}




Source: http://us3.php.net/manual/en/class.regexiterator.php
Problem:
                      Currently receiving a feed that returns
                       50 results, but you need to paginate
                            with 10 results per page.




Source: http://www.php.net/manual/en/spl.iterators.php
LimitIterator
Limit feed to 10 per page
$page = (int) $_GET['page'] ?: 1;
$perPage = 10;
$resultOffset = ($page * $perPage) - $perPage;
$it = new ArrayIterator($data);

// If the offset is greater than the data an exception is thrown "OutOfBoundsException"
try{
  foreach(new LimitIterator($it, $resultOffset, $perPage) AS $result) {
     echo "{$result['name']} <br>";
  }
} catch (OutOfBoundsException $e) {
  echo 'No Records Found';
} catch (Exception $e) {
  echo $e->getMessage();
}
Filter Iterators in the wild

            Symfony2
                ChainIterator
            •   CustomFilterIterator
            •   DateRangeFilterIterator
            •   ExcludeDirectoryFilterIterator
            •   FileTypeFilterIterator
            •   FilenameFilterIterator
            •   IgnoreVcsFilterIterator
            •   LimitDepthFilterIterator
            •   SizeRangeFilterIterator
            •   SortableIterator




Source: https://github.com/symfony/symfony/tree/master/src/Symfony/Component/Finder/Iterator
Other Iterators


              • AppendIterator
               • Iterate over multiple iterators
              • Caching Iterator
               • More of a look ahead, pointer is
                         always one stop behind


Source: http://www.php.net/manual/en/spl.iterators.php
Iterator Functions

                    • iterator_to_array
                    • iterator_apply
                     • similar to array_walk
                    • iterator_count
                     • used when iterator doesn’t
                               implement countable

Source: http://us.php.net/manual/en/ref.spl.php
Questions? Concerns? Complaints?
Thanks for listening!




    http://joind.in/talk/view/2971

More Related Content

What's hot

20150730 Sql AutoCommannotator - sac v2
20150730  Sql AutoCommannotator - sac v220150730  Sql AutoCommannotator - sac v2
20150730 Sql AutoCommannotator - sac v2Sharon Liu
 
Market Basket Analysis in R
Market Basket Analysis in RMarket Basket Analysis in R
Market Basket Analysis in RRsquared Academy
 
Django - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazosDjango - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazosIgor Sobreira
 
20220112 sac v1
20220112 sac v120220112 sac v1
20220112 sac v1Sharon Liu
 
The Many Facets of Apache Solr - Yonik Seeley
The Many Facets of Apache Solr - Yonik SeeleyThe Many Facets of Apache Solr - Yonik Seeley
The Many Facets of Apache Solr - Yonik Seeleylucenerevolution
 
SWP - A Generic Language Parser
SWP - A Generic Language ParserSWP - A Generic Language Parser
SWP - A Generic Language Parserkamaelian
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Michael Schwern
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 
Most Important C language program
Most Important C language programMost Important C language program
Most Important C language programTEJVEER SINGH
 
The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202Mahmoud Samir Fayed
 
CBSE Class XII Comp sc practical file
CBSE Class XII Comp sc practical fileCBSE Class XII Comp sc practical file
CBSE Class XII Comp sc practical filePranav Ghildiyal
 
Crafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterCrafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterRicardo Signes
 
Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3guesta3202
 
Data Structures Lab
Data Structures LabData Structures Lab
Data Structures LabNeil Mathew
 
Mcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singhMcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singhDIVYA SINGH
 

What's hot (20)

The Magic Of Elixir
The Magic Of ElixirThe Magic Of Elixir
The Magic Of Elixir
 
20150730 Sql AutoCommannotator - sac v2
20150730  Sql AutoCommannotator - sac v220150730  Sql AutoCommannotator - sac v2
20150730 Sql AutoCommannotator - sac v2
 
Market Basket Analysis in R
Market Basket Analysis in RMarket Basket Analysis in R
Market Basket Analysis in R
 
Django - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazosDjango - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazos
 
20220112 sac v1
20220112 sac v120220112 sac v1
20220112 sac v1
 
Lucene
LuceneLucene
Lucene
 
The Many Facets of Apache Solr - Yonik Seeley
The Many Facets of Apache Solr - Yonik SeeleyThe Many Facets of Apache Solr - Yonik Seeley
The Many Facets of Apache Solr - Yonik Seeley
 
Arrays matrix 2020 ab
Arrays matrix 2020 abArrays matrix 2020 ab
Arrays matrix 2020 ab
 
SWP - A Generic Language Parser
SWP - A Generic Language ParserSWP - A Generic Language Parser
SWP - A Generic Language Parser
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Most Important C language program
Most Important C language programMost Important C language program
Most Important C language program
 
wreewrer
wreewrerwreewrer
wreewrer
 
The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202
 
CBSE Class XII Comp sc practical file
CBSE Class XII Comp sc practical fileCBSE Class XII Comp sc practical file
CBSE Class XII Comp sc practical file
 
String slide
String slideString slide
String slide
 
Crafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterCrafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::Exporter
 
Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3Erlang Introduction Bcberlin3
Erlang Introduction Bcberlin3
 
Data Structures Lab
Data Structures LabData Structures Lab
Data Structures Lab
 
Mcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singhMcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singh
 

Viewers also liked (19)

InsideOut Development 2013 Holiday Card
InsideOut Development 2013 Holiday CardInsideOut Development 2013 Holiday Card
InsideOut Development 2013 Holiday Card
 
Sports Illustrated Models 2006
Sports Illustrated Models 2006Sports Illustrated Models 2006
Sports Illustrated Models 2006
 
Godrej company
Godrej companyGodrej company
Godrej company
 
Highest paying-jobs-in-america
Highest paying-jobs-in-americaHighest paying-jobs-in-america
Highest paying-jobs-in-america
 
Metadata Primer
Metadata PrimerMetadata Primer
Metadata Primer
 
The Business of Business Cards
The Business of Business CardsThe Business of Business Cards
The Business of Business Cards
 
Generation We
Generation WeGeneration We
Generation We
 
The Bull
The BullThe Bull
The Bull
 
Condom Fashion
Condom FashionCondom Fashion
Condom Fashion
 
Guns and Safety in Our Schools
Guns and Safety in Our SchoolsGuns and Safety in Our Schools
Guns and Safety in Our Schools
 
2012 GFPR Launch at IFPRI March 14 2013
2012 GFPR Launch at IFPRI March 14 20132012 GFPR Launch at IFPRI March 14 2013
2012 GFPR Launch at IFPRI March 14 2013
 
Infographic: Happy Employees
Infographic: Happy EmployeesInfographic: Happy Employees
Infographic: Happy Employees
 
AIDS.gov Mobile Presentation for US Conference on AIDS 2011
AIDS.gov Mobile Presentation for US Conference on AIDS 2011AIDS.gov Mobile Presentation for US Conference on AIDS 2011
AIDS.gov Mobile Presentation for US Conference on AIDS 2011
 
eMarketer Webinar: Key Digital Trends for 2012
eMarketer Webinar: Key Digital Trends for 2012eMarketer Webinar: Key Digital Trends for 2012
eMarketer Webinar: Key Digital Trends for 2012
 
The longboard
The longboardThe longboard
The longboard
 
The Birthday Cards I have received
The Birthday Cards I have receivedThe Birthday Cards I have received
The Birthday Cards I have received
 
UX and Semantic web UXCamp London 2014
UX and Semantic web UXCamp London 2014UX and Semantic web UXCamp London 2014
UX and Semantic web UXCamp London 2014
 
Social Business Design: Web 2.0 NYC
Social Business Design: Web 2.0 NYCSocial Business Design: Web 2.0 NYC
Social Business Design: Web 2.0 NYC
 
Carreira php
Carreira phpCarreira php
Carreira php
 

Similar to Unsung Heroes of PHP

Os Fetterupdated
Os FetterupdatedOs Fetterupdated
Os Fetterupdatedoscon2007
 
Out with Regex, In with Tokens
Out with Regex, In with TokensOut with Regex, In with Tokens
Out with Regex, In with Tokensscoates
 
MarcEdit Shelter-In-Place Webinar 6: Regular Expressions and .NET, A Primer
MarcEdit Shelter-In-Place Webinar 6: Regular Expressions and .NET, A PrimerMarcEdit Shelter-In-Place Webinar 6: Regular Expressions and .NET, A Primer
MarcEdit Shelter-In-Place Webinar 6: Regular Expressions and .NET, A PrimerTerry Reese
 
My First Rails Plugin - Usertext
My First Rails Plugin - UsertextMy First Rails Plugin - Usertext
My First Rails Plugin - Usertextfrankieroberto
 
Resource Routing in ExpressionEngine
Resource Routing in ExpressionEngineResource Routing in ExpressionEngine
Resource Routing in ExpressionEngineMichaelRog
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsDavey Shafik
 
Using Apache Solr
Using Apache SolrUsing Apache Solr
Using Apache Solrpittaya
 
Regex, Python & Twitter
Regex, Python & TwitterRegex, Python & Twitter
Regex, Python & TwitterStelian Firez
 
OWASP Top 10 : Let’s know & solve
OWASP Top 10 : Let’s know & solveOWASP Top 10 : Let’s know & solve
OWASP Top 10 : Let’s know & solveHarit Kothari
 
Thinking regular expressions
Thinking regular expressionsThinking regular expressions
Thinking regular expressionsPinMeTo
 
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...Arc & Codementor
 
pt-query-digest は Perl!!
pt-query-digest は Perl!!pt-query-digest は Perl!!
pt-query-digest は Perl!!Takafumi ONAKA
 
The NCAR RDA–Globus Integration: Experiences Developing a Modern Research Dat...
The NCAR RDA–Globus Integration: Experiences Developing a Modern Research Dat...The NCAR RDA–Globus Integration: Experiences Developing a Modern Research Dat...
The NCAR RDA–Globus Integration: Experiences Developing a Modern Research Dat...Globus
 
Exploiting Php With Php
Exploiting Php With PhpExploiting Php With Php
Exploiting Php With PhpJeremy Coates
 

Similar to Unsung Heroes of PHP (20)

Os Fetterupdated
Os FetterupdatedOs Fetterupdated
Os Fetterupdated
 
Out with Regex, In with Tokens
Out with Regex, In with TokensOut with Regex, In with Tokens
Out with Regex, In with Tokens
 
MarcEdit Shelter-In-Place Webinar 6: Regular Expressions and .NET, A Primer
MarcEdit Shelter-In-Place Webinar 6: Regular Expressions and .NET, A PrimerMarcEdit Shelter-In-Place Webinar 6: Regular Expressions and .NET, A Primer
MarcEdit Shelter-In-Place Webinar 6: Regular Expressions and .NET, A Primer
 
My First Rails Plugin - Usertext
My First Rails Plugin - UsertextMy First Rails Plugin - Usertext
My First Rails Plugin - Usertext
 
Rack Middleware
Rack MiddlewareRack Middleware
Rack Middleware
 
Regular expression for everyone
Regular expression for everyoneRegular expression for everyone
Regular expression for everyone
 
Resource Routing in ExpressionEngine
Resource Routing in ExpressionEngineResource Routing in ExpressionEngine
Resource Routing in ExpressionEngine
 
Dollar symbol
Dollar symbolDollar symbol
Dollar symbol
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP Streams
 
Using Apache Solr
Using Apache SolrUsing Apache Solr
Using Apache Solr
 
Regex, Python & Twitter
Regex, Python & TwitterRegex, Python & Twitter
Regex, Python & Twitter
 
OWASP Top 10 : Let’s know & solve
OWASP Top 10 : Let’s know & solveOWASP Top 10 : Let’s know & solve
OWASP Top 10 : Let’s know & solve
 
Thinking regular expressions
Thinking regular expressionsThinking regular expressions
Thinking regular expressions
 
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
Codementor Office Hours with Eric Chiang: Stdin, Stdout: pup, Go, and life at...
 
Grokking regex
Grokking regexGrokking regex
Grokking regex
 
pt-query-digest は Perl!!
pt-query-digest は Perl!!pt-query-digest は Perl!!
pt-query-digest は Perl!!
 
Czzawk
CzzawkCzzawk
Czzawk
 
Lettering js
Lettering jsLettering js
Lettering js
 
The NCAR RDA–Globus Integration: Experiences Developing a Modern Research Dat...
The NCAR RDA–Globus Integration: Experiences Developing a Modern Research Dat...The NCAR RDA–Globus Integration: Experiences Developing a Modern Research Dat...
The NCAR RDA–Globus Integration: Experiences Developing a Modern Research Dat...
 
Exploiting Php With Php
Exploiting Php With PhpExploiting Php With Php
Exploiting Php With Php
 

More from jsmith92

Intro to Micro-frameworks
Intro to Micro-frameworksIntro to Micro-frameworks
Intro to Micro-frameworksjsmith92
 
Doing more with LESS
Doing more with LESSDoing more with LESS
Doing more with LESSjsmith92
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overviewjsmith92
 
LESS is More
LESS is MoreLESS is More
LESS is Morejsmith92
 
Drawing the Line with Browser Compatibility
Drawing the Line with Browser CompatibilityDrawing the Line with Browser Compatibility
Drawing the Line with Browser Compatibilityjsmith92
 

More from jsmith92 (6)

Intro to Micro-frameworks
Intro to Micro-frameworksIntro to Micro-frameworks
Intro to Micro-frameworks
 
Doing more with LESS
Doing more with LESSDoing more with LESS
Doing more with LESS
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
 
LESS is More
LESS is MoreLESS is More
LESS is More
 
Drawing the Line with Browser Compatibility
Drawing the Line with Browser CompatibilityDrawing the Line with Browser Compatibility
Drawing the Line with Browser Compatibility
 

Recently uploaded

Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 

Unsung Heroes of PHP

  • 1. UNSUNG HEROES OF PHP JAKE SMITH http://joind.in/talk/view/2971
  • 2. Jake Smith [t] @jakefolio [w] http://jakefolio.com [e] me@jakefolio.com
  • 3. Clean Your Inputs with filter_var();
  • 4. filter_var/filter_input • Available since PHP 5.2.x • Validate or Sanitize variable/input • Input = GET, POST, ENV, COOKIE, SERVER • The input can not be manipulated Source: http://www.php.net/manual/en/filter.filters.php
  • 5. filter_input/filter_has_var Can not add additional fields to filter_input if ($_POST) { $_POST['additional_field'] = "valid string"; $result = filter_input(INPUT_POST, 'additional_field', FILTER_SANITIZE_STRING); // false $result2 = filter_has_var(INPUT_POST, 'additional_field'); // false }
  • 6. Filter - Email • FILTER_VALIDATE_EMAIL • FILTER_SANITIZE_EMAIL • Strip all non-email characters • Email standards based on RFC 822 Source: http://www.faqs.org/rfcs/rfc822.html
  • 7. Filter - email Official RFC822 regular expression (?:(?:rn)?[ t])*(?:(?:(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)? [ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?: [^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[ ["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+| Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*|(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["() <>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)*<(?:(?:rn)?[ t])*(?:@(?:[^()<>@,;:".[] 000-031]+(?:(?: (?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000- 031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*(?:,@(?:(?:rn)?[ t])*(?:[^()<>@,;:". [] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^() <>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["(<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*)*:(?:(?:rn)?[ t]) *)?(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)? [ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:r n)?[ t]))*"(?(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))| [([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:". []]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*>(?:(?:rn)?[ t])*)|(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["() <>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)*:(?:(?:rn)?[ t])*(?:(?:(?:[^()<>@,;:".[] 000-031]+(?:(?: (?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;: ".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:r n)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:. (?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)? [ t])*))*|(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:r n)?[ t])*)*<(?:(?:rn)?[ t])*(?:@(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)* ](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r ]|.)*](?:(?:rn)?[ t])*))*(?:,@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))| [([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:". []]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*)*:(?:(?:rn)?[ t])*)?(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["() <>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?: rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:". [] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^() <>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*>(?:(?:rn)?[ t]) *)(?:,s*(?:(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?: rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.| (?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:". []]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["() <>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*|(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:". []]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)*<(?:(?:rn)?[ t])*(?:@(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)? [ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?: (?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*(?:,@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000- 031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:". [] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*)*:(?:(?:rn)?[ t])*)?(?:[^() <>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:. (?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t])) *"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r ]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 000-031]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))| [([^[]r]|.)*](?:(?:rn)?[ t])*))*>(?:(?:rn)?[ t])*))*)?;s*)
  • 8. Filter - email Validate email examples: returns string if valid and false on failure if (preg_match('/^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4})$/', $email)) { echo "Email Good"; } // test good email address echo filter_var("chris@example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Good // test good email address echo filter_var("chris@a.b.c.example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Good // not allowed . before @ echo filter_var("chris.@example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad // not allowed .. in domain part echo filter_var("chris@example..com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad // not allowed . after @ echo filter_var("chris@.example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad // not allowed double @ echo filter_var("chris@@example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad // not allowed @ more than once anywhere echo filter_var("chris@exa@mple.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad // must have @ echo filter_var("chris#example.com", FILTER_VALIDATE_EMAIL) ? "goodn" : "badn"; // Bad Source: http://www.electrictoolbox.com/php-email-validation-filter-var/
  • 9. Filter - URL • FILTER_VALIDATE_URL • FILTER_SANITIZE_URL • Strip all non-url characters • URL standards based on RFC 2396 • Note that the function will only find ASCII URLs to be valid; internationalized domain names (containing non-ASCII characters) will fail. Source: http://www.faqs.org/rfcs/rfc2396
  • 10. Filter - url URLS to be tested for validation $urls = array( 'http://www.lonestarphp.com', 'http://www.lonestarphp.com', 'http://www.lonestarphp.com/blog', 'http://www.lonestarphp.com/index.html#anchor', 'http://www.lonestarphp.com/index.html?q=123', 'lonestarphp.com', 'www.lonestarphp.com', 'www.lonestarphp.com/blog', 'www.lonestarphp.com/index.html?q=123', '/index.html?q=123', 'https://www.lonestarphp.com/', 'https://localhost', 'https://localhost/', 'https://127.0.0.1/', 'http://.com', 'http://...', 'http://', 'http://i'me really trying to break this url!!!"£$"%$&*()' );
  • 11. Filter - url URLS validation combinations foreach ($urls AS $i => $url) { $result[$i]['base'] = filter_var($url, FILTER_VALIDATE_URL) ? 'PASS' : 'FAIL'; $result[$i]['path_required'] = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED) ? 'PASS' : 'FAIL'; $result[$i]['query_required'] = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED) ? 'PASS' : 'FAIL'; $result[$i]['path_scheme_required'] = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_PATH_REQUIRED) ? 'PASS' : 'FAIL'; }
  • 12. Filter - url URLS validation results
  • 13. Filter - String • FILTER_SANITIZE_STRING • Strip tags • Flags: • FILTER_FLAG_NO_ENCODE_QUOTES • FILTER_FLAG_STRIP_LOW / FILTER_FLAG_STRIP_HIGH • FILTER_FLAG_ENCODE_LOW / FILTER_FLAG_ENCODE_HIGH • FILTER_FLAG_ENCODE_AMP
  • 14. Filter - string Sanitize string utilizing different flags $string = "<strong>tcafén</strong>"; // Removes HTML tags (acts like strip_tags()) echo filter_var($string, FILTER_SANITIZE_STRING) . "<br>"; // This will remove the tab, the line break and HTML tags echo filter_var($string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); // This will remove the é and HTML tags. echo filter_var($string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
  • 15. Filter - string ASCII Table Source: http://www.asciitable.com/
  • 16. Filter - url ASCII Extended Table Source: http://www.asciitable.com/
  • 17. Filter - Boolean • FILTER_VALIDATE_BOOLEAN • returns true for: “yes”, 1, “on”, true • returns false for: “non”, 0, “off”, false
  • 18. Filter - boolean Sanitize string utilizing different flags $data = array( 'terms_of_service' => 'yes', 'logged_in_user' => true, 'forged_field' => 3523621, 'opt_in' => 'no' ); $result = filter_var_array($data, FILTER_VALIDATE_BOOLEAN); var_dump($result); foreach($result AS $key => $val) { if ($val === null) { echo $key . ' Can Not Validate <br>'; } if ($val === false) { echo $key . ' Failed Validation <br>'; } } /* OUTPUT array(4) { ["terms_of_service"]=> bool(true) ["logged_in_user"]=> bool(true) ["forged_field"]=> bool(false) ["opt_in"]=> bool(false) } */
  • 19. Filter - boolean Apply filter and flag on each element $result = filter_var_array($data, array( 'terms_of_service' => array( 'filter' => FILTER_VALIDATE_BOOLEAN, 'flags' => FILTER_NULL_ON_FAILURE ), 'logged_in_user' => array( 'filter' => FILTER_VALIDATE_BOOLEAN, 'flags' => FILTER_NULL_ON_FAILURE ), 'forged_field' => array( 'filter' => FILTER_VALIDATE_BOOLEAN, 'flags' => FILTER_NULL_ON_FAILURE ), 'opt_in' => array( 'filter' => FILTER_VALIDATE_BOOLEAN, 'flags' => FILTER_NULL_ON_FAILURE ) )); var_dump($result); /* OUTPUT array(4) { ["terms_of_service"]=> bool(true) ["logged_in_user"]=> bool(true) ["forged_field"]=> NULL ["opt_in"]=> bool(false) } */
  • 20. Filter - boolean Apply filter and flag to all elements with PHP 5.3 closure $result = filter_var_array($data, array_map(function() { return array( 'filter' => FILTER_VALIDATE_BOOLEAN, 'flags' => FILTER_NULL_ON_FAILURE ); }, $data) ); var_dump($result); /* OUTPUT array(4) { ["terms_of_service"]=> bool(true) ["logged_in_user"]=> bool(true) ["forged_field"]=> NULL ["opt_in"]=> bool(false) } */
  • 21. Filter - Integer • FILTER_VALIDATE_INT • FILTER_SANITIZE_INT • remove all characters except digits and +-
  • 22. Filter - integer Validate integer using extra options $year = filter_var('2032', FILTER_VALIDATE_INT, array( 'min_range' => 1927, 'max_range' => 2011) );
  • 23. Filter - Float • FILTER_VALIDATE_FLOAT • FILTER_FLAG_ALLOW_THOUSAND • FILTER_SANITIZE_FLOAT • FILTER_FLAG_ALLOW_FRACTION • FILTER_FLAG_ALLOW_SCIENTIFIC
  • 24. Filter - float Show different types of validation/sanitization // Removes the , even though it's a validate and not a sanitize $totalDonation[] = filter_var('123,523.72', FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND); // Fails because the ALLOW_THOUSAND flag is not set $totalDonation[] = filter_var('123,523.72', FILTER_VALIDATE_FLOAT); // No sanitization needed $totalDonation[] = filter_var('123,523.72', FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_THOUSAND | FILTER_FLAG_ALLOW_FRACTION); // Removes , $totalDonation[] = filter_var('123,523.72', FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); $sciNotation = filter_var('2352e28', FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_SCIENTIFIC); foreach($totalDonation AS $donation) { // Failed validation if false returned. if ($donation === false) { echo "FAILED VALIDATION"; } echo $donation . "<br>"; } echo $sciNotation;
  • 25. Putting it all together!
  • 26. filter_input_array Basic Contact Form HTML <form action="" method="post"> <p> <label>First Name</label><br> <input type="text" name="first_name"> </p> <p> <label>Last Name</label><br> <input type="text" name="last_name"> </p> <p> <label>E-mail</label><br> <input type="email" name="email"> </p> <p> <label>Cell Number</label><br> <input type="text" name="cell_phone"> </p> <p> <label>Feedback</label><br> <textarea name="message">Please add feedback</textarea> </p> <p> <label>Disclaimer</label><br> <input type="checkbox" name="disclaimer" value="yes"> Check box for generic disclaimer </p> <p><input type="submit" value="Submit Form"></p> </form>
  • 27. filter_input_array Basic Contact Form without filter_input_array if ($_POST) { foreach($_POST AS $id => $val) { $_POST[$id] = strip_tags($val); } if (empty($_POST['first_name'])) { $errors[] = "First Name is a required field."; } if (empty($_POST['last_name'])) { $errors[] = "Last Name is a required field."; } if (!preg_match( '/^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4})$/', $_POST['email'])) { $errors[] = "Email is invalid."; } if (!isset($_POST['disclaimer']) || $_POST['disclaimer'] != 'yes') { $errors[] = "You must accept the disclaimer."; } }
  • 28. Filter - string Basic Contact Form WITH filter_input_array if ($_POST) { $results = filter_input_array(INPUT_POST, array( // Strip Tags 'first_name' => FILTER_SANITIZE_STRING, // Strip Tags 'last_name' => FILTER_SANITIZE_STRING, // Validate Email 'email' => FILTER_VALIDATE_EMAIL, // Strip all non-numeric characters 'cell_phone' => FILTER_SANITIZE_NUMBER_INT, // Strip Tags 'message' => FILTER_SANITIZE_STRING, // Validate Boolean value, return null if can not evaluate to boolean 'disclaimer' => array( 'filter' => FILTER_VALIDATE_BOOLEAN, 'flags' => FILTER_NULL_ON_FAILURE ) )); // Set Errors foreach($results AS $id => $val) { if ($val === NULL || $val === false) { $errors[] = "{$id} is invalid."; } } }
  • 30. XML Libraries • SimpleXML • DOMDocument • XMLReader/Writer
  • 31. XML Section Data Feed (Compliments of BreweryDB.com) $data = <<<XML <beers> <beer> <id>6204</id> <name>"My" Bock</name> <description> Amber, malty and not too heavy, all around favorite even for the drinkers of the yellow fizzy stuff </description> <brewery>1428</brewery> <created>2011-06-01T09:39:12+00:00</created> <updated/> </beer> <beer> <id>7219</id> <name>"Ptarmigan" Pilsner</name> <description> Ptarmigan Pilsner our GABF Silver Medal Winner is A traditional European Style Pilsner with a light hop aroma, smooth malt flavor and a distinctively clean finish. </description> <brewery>64</brewery> <created>2011-02-25T05:40:25+00:00</created> <updated/> </beer> <beer> <id>7218</id> <name>"Wheeler" Wheat</name> <description> Wheeler Wheat is a light and refreshing beer to quench your thirst after a hard day of adventure seeking. An American-style wheat beer with just a hint of orange peel and coriander, enjoy it with a slice of fruit if you like, we recommend a slice of orange! </description> <brewery>64</brewery> <created>2011-02-25T05:36:45+00:00</created> <updated/> </beer> </beers> XML;
  • 32. SimpleXML • Tree Parser • Really awesome for quick and dirty reading • Xpath built-in Source: http://us.php.net/manual/en/class.simplexmlelement.php
  • 33. SimpleXML Read XML string and inject node //$xml = simplexml_load_file(); $xml = simplexml_load_string($data); // $xml = new SimpleXMLElement($data); echo "Enjoy some {$xml->beer[0]->name} <br>"; $result = $xml->xpath('//beer[brewery=64]'); foreach($result AS $beer) { echo "Found a {$beer->name} <br>"; } // Add my brew $myBeer = $xml->addChild('beer'); $myBeer->addChild('id', 12252); $myBeer->addChild('name', '512 Pecan Porter'); $myBeer->addChild('description', 'Delicious beer from Austin go try!'); $exportedXML = $xml->asXML(); // $xml->saveXML(); Source: http://us.php.net/manual/en/class.simplexmlelement.php
  • 34. SimpleXML Scrape Craigslist - Searching for “leather” under “furniture” $html = new DOMDocument(); $html->loadHTML(file_get_contents('http://dallas.craigslist.org/search/fua? query=leather&srchType=A&minAsk=&maxAsk=')); $xml = simplexml_import_dom($html); $results = $xml->xpath('//p[@class="row"]'); foreach($results as $listing) { // Strip the " -" from the end of the title $title = substr($listing->a, 0, -2); // Get Image filename from HTML id $imagePath = substr( $listing->span[0]->attributes()->id, strpos($listing->span[0]->attributes()->id, ':')+1 ); echo '<p>'; echo ($imagePath) ? '<img src="http://images.craigslist.org/' . $imagePath . '">' : ''; echo $title; echo '</p>'; } Source: http://us.php.net/manual/en/class.simplexmlelement.php
  • 35. DOMDocument • Tree Parser • Great at importing HTML/XHTML • Great at modifying/injecting nodes • Xpath built-in Source: http://us.php.net/domdocument
  • 36. DOMDocument Read XML string and inject node $newBeer = <<<XML <beer> <id>3252</id> <name>512 Pecan Porter</name> <description> Delicious nutty beer. </description> <brewery>23</brewery> <created>2011-06-11T05:36:45+00:00</created> <updated/> </beer> XML; $xml = new DOMDocument(); $xml->loadXML($exportedXML); // Show name of first beer in xml document (from root, no xpath query) echo $xml->getElementsByTagName('beer')->item(0)->getElementsByTagName('name')->item(0)->nodeValue; $xpath = new DOMXpath($xml); $res = $xpath->query('//beer[1]/name'); // Show name of first beer in xml document (DOMXpath) echo $res->item(0)->nodeValue; $beerXML = new DOMDocument(); $beerXML->loadXML($newBeer); $node = $xml->importNode($beerXML->documentElement, true); $xml->appendChild($node); // $xml->replaceChild(); // $xml->removeChild(); echo $xml->saveXML(); Source: http://us.php.net/domdocument
  • 37. DOMDocument Scrape Craigslist - Searching for “leather” under “furniture” $html = new DOMDocument(); $html->loadHTML(file_get_contents('http://dallas.craigslist.org/search/fua? query=leather&srchType=A&minAsk=&maxAsk=')); $xpath = new DOMXpath($html); $result = $xpath->query('//p[@class="row"]'); foreach($result AS $listing) { $title = substr($listing->getElementsByTagName('a')->item(0)->nodeValue, 0, -2); $imagePath = $listing->getElementsByTagName('span')->item(0)->getAttribute('id'); $imagePath = substr($imagePath, strpos($imagePath, ':')+1); echo '<p>'; echo ($imagePath) ? '<img src="http://images.craigslist.org/' . $imagePath . '">' : ''; echo $title; echo '</p>'; } Source: http://us.php.net/domdocument
  • 38. XMLReader/Writer • Pull Parser • Full Steam Ahead - only moves forward • Great for large XML documents • Reads/Writes line by line, small memory footprint
  • 39. XMLReader Iterate Feed $reader = new XMLReader(); $reader->open("http://www.brewerydb.com/api/beers/?apikey={$apiKey}"); while($reader->read()) { if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == "beer") { echo "<p>"; } if ($reader->nodeType == XMLReader::ELEMENT || $reader->nodeType == XMLReader::TEXT) { switch($reader->name) { case "id"; case "name"; case "brewery"; case "description"; case "created"; case "updated"; echo $reader->name . ": "; continue; break; default: } if ($reader->nodeType == XMLReader::TEXT && $reader->value) { echo $reader->value . "<br>"; } if ($reader->nodeType == XMLReader::END_ELEMENT && $reader->name == "beer") { echo "</p>"; } } } Source: http://us.php.net/manual/en/class.xmlreader.php
  • 40. XMLWriter Headers and Data header("Content-Type: text/html/force-download"); header("Content-Disposition: attachment; filename=beers.xml"); $beerArray = array( 0 => array( 'id' => 12451, 'name' => 'Shiner 102', 'brewery' => 526, 'description' => 'Lone Star Approved!', 'created' => '2011-06-11T05:36:45+00:00' ), 1 => array( 'id' => 23551, 'name' => '512 Pecan Porter', 'brewery' => 126, 'description' => 'A bit nutty', 'created' => '2011-06-11T05:36:45+00:00' ), 2 => array( 'id' => 35351, 'name' => 'Brooklyn Lager', 'brewery' => 226, 'description' => 'New York City?', 'reviews' => array( 0 => 'Great', 1 => 'Good', 2 => 'Above Average' ), 'created' => '2011-06-11T05:36:45+00:00' ), ); Source: http://us.php.net/manual/en/ref.xmlwriter.php
  • 41. XMLWriter Setup class XMLRecursiveIteratorIterator extends RecursiveIteratorIterator { protected $xml; public function __construct($it, $flag = RecursiveIteratorIterator::SELF_FIRST, XMLWriter $xml) { parent::__construct($it, $flag); $this->xml = $xml; } public function endChildren() { $this->xml->endElement(); } } $xml = new XMLWriter(); $xml->openURI('php://output'); $xml->startDocument('1.0', 'UTF-8'); $xml->setIndent(4); Source: http://us.php.net/manual/en/ref.xmlwriter.php
  • 42. XMLWriter Iteration foreach($beers AS $key => $value) { // If back to the top level create new beer if ($beers->getDepth() == 0) { $xml->startElement('beer'); continue; } // Change current parent to reviews if ($key == "reviews") { $currentParent = "reviews"; } // Check if current value is a review or not $current = (is_int($key) && $currentParent == "reviews") ? "review" : $key; $xml->startElement($current); // Don't end the element if it is the start of a child list if (!$beers->hasChildren()) { $xml->text($value); $xml->endElement(); } } // Close all open tags $xml->endDocument(); Source: http://us.php.net/manual/en/ref.xmlwriter.php
  • 43. XML Recap - SimpleXML • Great for reading XML • Is Iterable (we’ll talk more on this) • Is NOT the end all be all for XML • Has xpath (tree traversing)
  • 44. XML Recap - DOMDocument • Great for manipulating XML • Can properly load (X)HTML files • Has xpath (tree traversing)
  • 45. XML Recap - XMLReader/Writer • Extremely fast • Handles stream context for source • Best used with large XML docs or streams • Forward moving (pull)
  • 47. What is an Iterator? “ An iterator is an object that enables a programmer to traverse a container. Various types of iterators are often provided via a container's interface. ” Source: http://en.wikipedia.org/wiki/Iterator
  • 48. Quotes in the Community “ PHP also have a lot of awesome features; at least two of them are in my opinion largely underused: Iterators and Streams. Fabien Potencier (Lead Developer of Symfony Project) ” Source: http://fabien.potencier.org/article/44/php-iterators-and-streams-are-awesome
  • 49. Iterator Interfaces • Traversable • Iterator • RecursiveIterator • Countable • SeekableIterator Source: http://www.php.net/manual/en/spl.iterators.php
  • 50. Interface - Iterator Iterator extends Traversable { /* Methods */ abstract public mixed current ( void ) abstract public scalar key ( void ) abstract public void next ( void ) abstract public void rewind ( void ) abstract public boolean valid ( void ) } Source: http://us.php.net/manual/en/class.iterator.php
  • 51. Interface - RecursiveIterator RecursiveIterator extends Iterator { /* Methods */ public RecursiveIterator getChildren ( void ) public bool hasChildren ( void ) /* Inherited methods */ abstract public mixed Iterator::current ( void ) abstract public scalar Iterator::key ( void ) abstract public void Iterator::next ( void ) abstract public void Iterator::rewind ( void ) abstract public boolean Iterator::valid ( void ) } Source: http://www.php.net/manual/en/spl.iterators.php
  • 53. DirectoryIterator Output directory content for Zend Framework $it = new DirectoryIterator('lib/Zend'); foreach ($it AS $file) { echo $file->getFilename() . "<br>"; } OUTPUT: . .. .DS_Store Acl Acl.php Amf Application Application.php Auth Auth.php Barcode Barcode.php Cache Cache.php Captcha Cloud CodeGenerator Config Config.php Console Controller Crypt Crypt.php Currency Currency.php Date Source: http://us.php.net/manual/en/class.directoryiterator.php
  • 54. DirectoryIterator - SPLFileInfo Methods available $it = new DirectoryIterator('lib/Zend'); foreach ($it AS $file) { echo $file->getFilename() . "<br>"; } OUTPUT: /* Methods available for $file public int getATime ( void ) public string getBasename ([ string $suffix ] ) public int getCTime ( void ) public string getExtension ( void ) public SplFileInfo getFileInfo ([ string $class_name ] ) public string getFilename ( void ) public int getGroup ( void ) public int getInode ( void ) public string getLinkTarget ( void ) public int getMTime ( void ) public int getOwner ( void ) public string getPath ( void ) public SplFileInfo getPathInfo ([ string $class_name ] ) public string getPathname ( void ) public int getPerms ( void ) public string getRealPath ( void ) public int getSize ( void ) public string getType ( void ) public bool isDir ( void ) public bool isExecutable ( void ) public bool isFile ( void ) public bool isLink ( void ) public bool isReadable ( void ) public bool isWritable ( void ) */ Source: http://us.php.net/manual/en/class.splfileinfo.php
  • 55. FileSystemIterator (PHP 5.3.x) Output directory content for Zend Framework $it = new FileSystemIterator('lib/Zend'); foreach ($it AS $path => $file) { echo $path . " - " . $file->getFilename() . "<br>"; } OUTPUT: lib/Zend/.DS_Store - .DS_Store lib/Zend/Acl - Acl lib/Zend/Acl.php - Acl.php lib/Zend/Amf - Amf lib/Zend/Application - Application lib/Zend/Application.php - Application.php lib/Zend/Auth - Auth lib/Zend/Auth.php - Auth.php lib/Zend/Barcode - Barcode lib/Zend/Barcode.php - Barcode.php lib/Zend/Cache - Cache lib/Zend/Cache.php - Cache.php lib/Zend/Captcha - Captcha lib/Zend/Cloud - Cloud lib/Zend/CodeGenerator - CodeGenerator lib/Zend/Config - Config lib/Zend/Config.php - Config.php lib/Zend/Console - Console Source: http://us.php.net/manual/en/class.filesystemiterator.php
  • 56. GlobIterator (PHP 5.3.x) Output directory content for Zend Framework $it = new GlobIterator('lib/Zend/*'); foreach ($it AS $path => $file) { echo $path . " - " . $file->getFilename() . "<br>"; } OUTPUT: lib/Zend/Acl - Acl lib/Zend/Acl.php - Acl.php lib/Zend/Amf - Amf lib/Zend/Application - Application lib/Zend/Application.php - Application.php lib/Zend/Auth - Auth lib/Zend/Auth.php - Auth.php lib/Zend/Barcode - Barcode lib/Zend/Barcode.php - Barcode.php lib/Zend/Cache - Cache lib/Zend/Cache.php - Cache.php lib/Zend/Captcha - Captcha lib/Zend/Cloud - Cloud lib/Zend/CodeGenerator - CodeGenerator lib/Zend/Config - Config lib/Zend/Config.php - Config.php lib/Zend/Console - Console Source: http://us.php.net/manual/en/class.globiterator.php
  • 57. RecursiveTreeIterator (PHP 5.3.x) Output ASCII view of Directory Structure $it = new RecursiveDirectoryIterator('lib/Zend'); foreach (new RecursiveTreeIterator($it) AS $file) { echo $file . "n"; } OUTPUT: |-lib/Zend/Acl | |-lib/Zend/Acl/Assert | | -lib/Zend/Acl/Assert/Interface.php | |-lib/Zend/Acl/Exception.php | |-lib/Zend/Acl/Resource | | -lib/Zend/Acl/Resource/Interface.php | |-lib/Zend/Acl/Resource.php | |-lib/Zend/Acl/Role | | |-lib/Zend/Acl/Role/Interface.php | | |-lib/Zend/Acl/Role/Registry | | | -lib/Zend/Acl/Role/Registry/Exception.php | | -lib/Zend/Acl/Role/Registry.php | -lib/Zend/Acl/Role.php |-lib/Zend/Acl.php |-lib/Zend/Amf | |-lib/Zend/Amf/Adobe | | |-lib/Zend/Amf/Adobe/Auth.php | | |-lib/Zend/Amf/Adobe/DbInspector.php | | -lib/Zend/Amf/Adobe/Introspector.php | |-lib/Zend/Amf/Auth | | -lib/Zend/Amf/Auth/Abstract.php | |-lib/Zend/Amf/Constants.php | |-lib/Zend/Amf/Exception.php Source: http://us.php.net/manual/en/class.recursivetreeiterator.php
  • 59. Problem: Need to view all files in a directory, but it keeps returning Version Control folders (.svn and .git). Source: http://www.php.net/manual/en/spl.iterators.php
  • 60. FilterIterator Do not show Version Control folders class NoVCSIterator extends FilterIterator { public function accept() { $file = $this->getInnerIterator()->current(); if ($file->isDir() && ($file->getFilename() == '.git' || $file->getFilename() == '.svn')) { return false; } return true; } }
  • 61. Problem: I need to see all images that are over 5MB that have been uploaded. Source: http://www.php.net/manual/en/spl.iterators.php
  • 62. FilterIterator Only show images greater than 5MB class LargeImageFilter extends FilterIterator { protected $safeImageTypes = array('jpg', 'gif', 'png'); public function __construct(Iterator $it, $imageTypes) { parent::__construct($it); if (count($imageTypes) > 0) { $this->safeImageTypes = $imageTypes; } } public function accept() { $file = $this->getInnerIterator()->current(); if (in_array($file->getExtension(), $this->safeImageTypes) && $file->getSize() > 5242880) return true; } } $dir = new DirectoryIterator(UPLOADS_PATH); foreach(new LargeImageFilter($dir) AS $file) { echo $file->getFileName(); }
  • 63. RegexIterator Move integers from front to the back (example from php.net) /* * RegexIterator::MATCH * RegexIterator::REPLACE * RegexIterator::ALL_MATCHES * RegexIterator::SPLIT */ $a = new ArrayIterator(array('test1', 'test2', 'test3')); $it = new RegexIterator($a, '/^(test)(d+)/', RegexIterator::REPLACE); $it->replacement = '$2:$1'; foreach($it AS $el) { echo $el; } Source: http://us3.php.net/manual/en/class.regexiterator.php
  • 64. Problem: Currently receiving a feed that returns 50 results, but you need to paginate with 10 results per page. Source: http://www.php.net/manual/en/spl.iterators.php
  • 65. LimitIterator Limit feed to 10 per page $page = (int) $_GET['page'] ?: 1; $perPage = 10; $resultOffset = ($page * $perPage) - $perPage; $it = new ArrayIterator($data); // If the offset is greater than the data an exception is thrown "OutOfBoundsException" try{ foreach(new LimitIterator($it, $resultOffset, $perPage) AS $result) { echo "{$result['name']} <br>"; } } catch (OutOfBoundsException $e) { echo 'No Records Found'; } catch (Exception $e) { echo $e->getMessage(); }
  • 66. Filter Iterators in the wild Symfony2 ChainIterator • CustomFilterIterator • DateRangeFilterIterator • ExcludeDirectoryFilterIterator • FileTypeFilterIterator • FilenameFilterIterator • IgnoreVcsFilterIterator • LimitDepthFilterIterator • SizeRangeFilterIterator • SortableIterator Source: https://github.com/symfony/symfony/tree/master/src/Symfony/Component/Finder/Iterator
  • 67. Other Iterators • AppendIterator • Iterate over multiple iterators • Caching Iterator • More of a look ahead, pointer is always one stop behind Source: http://www.php.net/manual/en/spl.iterators.php
  • 68. Iterator Functions • iterator_to_array • iterator_apply • similar to array_walk • iterator_count • used when iterator doesn’t implement countable Source: http://us.php.net/manual/en/ref.spl.php
  • 70. Thanks for listening! http://joind.in/talk/view/2971