Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

PHP: Parsing SimpleXML nodes with namespaces

SimpleXML is one of the easiest parsers to use, but when it comes to namespaces, things get just a little bit tricker.

You'll run into them when you're parsing media RSS feeds such as:

  • FlickR (media:thumbnail, media:category, media:content)
  • YouTube API (yt:duration, yt:statistics, gd:rating, gd:comments)
  • or Yahoo Weather (yweather:location, yweather:astronomy)

They might be a bit gay to deal with, but luckily it isn't too much harder.

9
Namespaces, almost as gay as this guy.

The trick is having to gather the namespace children before pulling the element you want.

Using this short sample XML from FlickR.

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:creativeCommons="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html"
xmlns:flickr="urn:flickr:">
<channel>
<item>
<title>発売中</title>
...
<dc:date.Taken>2010-06-13T13:08:52-08:00</dc:date.Taken>
<media:thumbnail url="http://farm6.static.flickr.com/5122/5370686057_cb21430ac5_s.jpg" height="75" width="75" />
...
</item>
</channel>
</rss>

You can use this PHP code to extract the "media:thumbnail" elements from the RSS item.

$entries = simplexml_load_file('http://api.flickr.com/services/feeds/photos_public.gne?tags=tokyo&format=rss_200');
$namespaces = $entries->getNamespaces(true);

foreach ($entries->channel->item as $feeditem) {
$thumbnail = $feeditem->children($namespaces['media'])->thumbnail;
$attr = $thumbnail->attributes();

echo '<pre>';
echo "URL = {$attr['url']}, width = {$attr['width']}, height = {$attr['height']}\n";
echo print_r($attr, true);
echo '</pre>';
}

The code was based off the source from PHPFreaks, but modified to avoid using the URI of namespaces as it makes the code ugly.

Enjoy!

[ Source ]

Tutorial: Logic behind resizing image and keeping aspect ratio

Once in a while you'll encounter this problem and the logic usually remains the same regardless of what language you're using.

Use cases are:

  1. Resize to given width and height, ignoring image aspect ratio
  2. Resize to given width, keeping height in the correct aspect ratio
  3. Resize to height, keeping height in the correct aspect ratio

The tutorial/example below is given in PHP, but if you skim the lines of code its just some common control statements that are used.

if (!file_exists($resized_file)) {
$image_info = image_get_info($input_file);
$w = $image_info['width'];
$h = $image_info['height'];

if (!$reso['keep_ratio']) {
$w = intval($reso['width'] != -1 ? $reso['width'] : $image_info['width'] * ($reso['height'] / $image_info['height']));
$h = intval($reso['height'] != -1 ? $reso['height'] : $image_info['height'] * ($reso['width'] / $image_info['width']));
}

else {
// Check if resize needed ...
if (($image_info['width'] > $reso['width']) || ($image_info['height'] > $reso['height'])) {
// Compare ratios to determine which side is longer
// If width ratio < height ratio, then use height/width, otherwise width/height
$resize_by_width = (($image_info['width'] / $reso['width']) > ($image_info['height'] / $reso['height']));

$resize_ratio = ($resize_by_width ? $reso['width'] / $image_info['width'] : $reso['height'] / $image_info['height']);

$w = $image_info['width'] * $resize_ratio;
$h = $image_info['height'] * $resize_ratio;
}
}

image_resize($input_file, $resized_file, $w, $h);
}

Hopefully thats fairly easy to translate into another programming language.

PHP: List methods/functions in a class or object

Use the built-in function get_class_methods() which returns an array of method names. It'll take a class or object as the first argument.

A Brief, Incomplete, and Mostly Wrong History of Programming Languages

An absolute cracker of a nerdy post by James Iry, author of One Div Zero.

See it here: A Brief, Incomplete, and Mostly Wrong History of Programming Languages

Couldn't agree more with 1996-2001 =P

Python: PHP equivalent of in_array() for Python

To check if a value exists within a PHP array:

if (in_array("x", $php_array)) {
// Exists
}

To check if a value exists within a Python list:

if "x" in python_list:
# Exists

PHP: SimpleXML->xpath() not working correctly

It has to do with the namespace and document types not being set properly, so xpath() doesn't know how to parse it.

If you're only after a quick and dirty way of parsing (X)HTML, then all you need is to load it into a DOMDocument to create the SimpleXML object.

$contents = @file_get_contents($url);

if (!$contents) { echo "Error for some reason.";
return;
}

// Parse the document
$doc = new DOMDocument();
$doc->strictErrorChecking = FALSE;
$doc->loadHTML($contents);

$xml = simplexml_import_dom($doc);

foreach ($xml->xpath('//img') as $image) {
$images[] = (string)$image['src'];
}

[ Source ]

HTTP headers to force a file to download

If you're protecting a file from direct access, you can add some sort of gateway script which spits out the content without redirecting and exposing the URL.

To do that (using PHP in this example), send the following headers to the browser before displaying the content.

$filename = "files/path/something.zip";
$content = file_get_contents($filename);

header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"hello world.zip\"");
header("Content-Type: " . mime_content_type($filename));
header("Content-Length: " . strlen($content));

echo $content;
exit();

The headers are in the same format no matter what language you use, so it should be fairly simple to port it.

[ Source ]

Postgres SQL: phpPgAdmin comes up with "Login disallowed for security reasons"

blah

Edit "conf/config.inc.php" and search through the file for:

$conf['extra_login_security'] = true;

Set the value to "false" and logins should now work.

PHP: Get the longest string (or length) in an array

To quickly get the longest string in an array, use the following function.

function longest_string_in_array($array) {
  $mapping = array_combine($array, array_map('strlen', $array));
  return array_keys($mapping, max($mapping));
}

If you need the length of the longest string, use this little snippet.

$maxlen = max(array_map('strlen', $array));

[ Sources ]

Twig - The Flexible, Fast and Secure Template Language for PHP

It really feels weird reading something like this, especially when you've had nothing to do with it!

http://www.twig-project.org

I've personally never tried it before, but hey if its any good let me know.

PHP: Easy way to strip unwanted characters off a string

$output = preg_replace('/[^\da-z A-Z]/', '', $input);

This will remove any characters other than:

  • \d (Numbers)
  • a-z (Lower case characters)
  • A-Z (Upper case characters)
  • And spaces (There is a space between "z" and "A")

PHP: Get contents from a page protected by password

Retrieving the contents of a webpage in PHP5 is really easy these days. You simply make a call to file_get_contents() and it automatically handles the request and parsing for you. It even works for local files!

Now, what if the page you're trying to access requires authentication? Luckily, its not difficult to do this either.

// Set up the authentication information
$url = "http://www.example.com/admin";
$username = "administrator";
$password = "p455word";

// Set up the context stream
$context_info = array(
  'http' => array(
    'header' => "Authorization: Basic " . base64_encode("$username:$password")
  )
);
$context = stream_context_create($context_info);

// Retrieve the page
$data = file_get_contents($url, false, $context);

The data scraped from the page should now be contained within the $data variable.

[ Source ]

PHP: Easy way to parse XML and RSS feeds

With PHP 5, you can use either simplexml_load_file() or simplexml_load_string() to get an instance of the SimpleXMLElement class.

This is a massively simplified feed from Digg. (Shame the example didn't include anything about Kanye West being a big jackass to Taylor Swift)

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
  <title>digg.com: Stories / Popular</title>
  <language>en-us</language>
  <description>digg.com: Stories / Popular</description>
  <link>http://digg.com/</link>
  <item>
   <title>6 Russian Volcanoes Erupt Simultaneously</title>
   <link>http://feeds.digg.com/~r/digg/popular/~3/ufca-hKu7hM/6_Russian_Volcanoes_Erupt_Simultaneously</link>
   <description>*****</description>
   <pubDate>Wed, 16 Sep 2009 22:30:01 +0000</pubDate>
   <guid isPermaLink="false">http://digg.com/environment/6_Russian_Volcanoes_Erupt_Simultaneously</guid>
  </item>
  <item>
   <title>Happiness: The New Currency in France</title>
   <link>http://feeds.digg.com/~r/digg/popular/~3/7hQDWvQwx5A/Happiness_The_New_Currency_in_France</link>
   <description>Gross domestic product, inflation, unemployment- these are old-fashioned, Anglo-Saxon indicators of national wellbeing, says the president of France. From now on, the country's economic progress will be measured in terms of happiness.</description>
   <pubDate>Wed, 16 Sep 2009 22:10:02 +0000</pubDate>
   <guid isPermaLink="false">http://digg.com/health/Happiness_The_New_Currency_in_France</guid>
  </item>
  <item>
   <title>The 15 Weirdest Music Videos Of All Time</title>
   <link>http://feeds.digg.com/~r/digg/popular/~3/QTH3TyAZma0/The_15_Weirdest_Music_Videos_Of_All_Time</link>
   <description>Music videos changed the music industry completely. Artists were finally given a "visual voice" and fans were able to put faces with names. Musicians are often a little quirky however, resulting in many truly bizarre videos.</description>
   <pubDate>Wed, 16 Sep 2009 22:00:01 +0000</pubDate>
   <guid isPermaLink="false">http://digg.com/music/The_15_Weirdest_Music_Videos_Of_All_Time</guid>
  </item>
</channel>
</rss>

To parse the items in this list, simply use the following.

$rss = simplexml_load_file("http://feeds.digg.com/digg/popular.rss");

echo "Parsing feed with title: " . $rss->channel->title;

foreach ($rss->channel->item as $item) {
  echo $item->title;
  echo $item->link;
  echo $item->description;
  echo $item->guid;
}

And there you have it, very simple.

Detecting PHP output buffer leaks

If you want to check for "ob_start()" leaks or incorrectly closed buffers, add the check at the end of each file you wish to check.

If running PHP in command line mode, by default there are no buffer levels.
However, when the request is from a browser, the default buffer level is 1.

So, at the end of the script, add the following.
if (ob_get_length() && ob_get_level() > 1) {
error_log("ERROR: Output buffering leakage detected: ({$_SERVER['REQUEST_METHOD']}) {$_SERVER['REQUEST_URI']}");
error_log("ERROR: Output buffering args:\n" . print_r($_SERVER['argv'], true));
}
The "ob_get_length()" checks if there is any data in the current buffer.
Typically this would be sufficient in command line, but since a browser request has one level of buffer set, we need to also check "ob_get_level()".

PHP output buffering nightmare

While going through some code at work, I noticed that some output buffering wasnt being ended correctly.

The number of ob_start()'s werent being ended properly, causing a buffer to carry through all the way to the end of the page.

Eventually it was found to be a simple mistake.
The use of "ob_clean()" instead of "ob_end_clean()".
$ret = ob_get_contents();
ob_clean();
return $ret;
Please! Just use "ob_start()" and "ob_get_clean()" !!!
They're both one line, respect the current buffering level and incredibly simple to use!

PHP Parse error: syntax error, expecting T_PAAMAYIM_NEKUDOTAYIM

What the hell?

PHP Parse error: syntax error, unexpected ')', expecting T_PAAMAYIM_NEKUDOTAYIM in file.php on line 12345

According to Wikipedia:
Paamayim Nekudotayim is the official name for the Scope Resolution Operator (::) in PHP. It means "twice colon" or "double colon" in Hebrew.
 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog