phpacademy.org Offers FREE PHP Tutorials

Posted by Nessa | Posted in uncategorized | Posted on 31-03-2011

2

There’s a new site out there that’s offering high quality PHP video tutorials – for FREE!  All you PHP gurus, check out phpacademy.org.  They currently have over 200 PHP and MySQL tutorials for both beginner and intermediate users.  Unlike other PHP tutorial sites, phpacademy is unique because the tutorials are all on video, so there’s less boring reading.  Did I also mention that it’s free?

Head on over and check them out, feel free to post comments and reviews here!

Error Installing APC via PECL

Posted by Nessa | Posted in uncategorized | Posted on 27-02-2011

1

I got the following error when compiling APC on one of the servers:

/root/APC-3.1.6/apc.c:464: error: ‘apc_regex’ has no member named ‘nreg’

To fix this, make sure that PHP is installed with PCRE support (type php -m for a list of modules), then install the pcre-devel package:

yum install pcre-devel

Using POST Variables Outside the Loop

Posted by Nessa | Posted in uncategorized | Posted on 24-02-2011

4

I was working on this mini contact form the other day where a user basically enters in a bunch of info, the form submits to itself via PHP_SELF, and sends out an email. Oddly enough, once I transferred the form to its permanent home and spent a decent chunk of time trying to figure out why it wasn’t working anymore, I discovered that my developement box still had register_globals enabled from a previous project I was working on.  Doh!

This is part of my loop, which basically just grabs all the $_POST variables and their values to compare them with a previous array ($required) that specifies what values should be present in order for the mailer to determine how much of the form was completed:


// Values passed: domain,email

foreach($_POST as $name => $value) {
if(in_array($name,$required)){
if(empty($value) && value != 0 ){
$complete=0;
}else{
$complete=1;
}
}
}

(Ignore the fact that WordPress reformats my coding)

The problem is, when I went to use the names of the variables or their values later in the script, I got nothing. This of course would work with register_globals enabled, but since I prefer to work in a more secure environment, a small adjustment was needed in to make those variables available outside the loop:


// Values passed: domain,email

foreach($_POST as $name => $value) {
$$name = trim($value);
if(in_array($name,$required)){
if(empty($value) && value != 0 ){
$complete=0;
}else{
$complete=1;
}
}
}

Pretty simple stuff, eh? All I did here was tell the loop to actually create a variable and value for each $_POST value that was part of the foreach loop. From there, all I had to do was use these values are normal ($domain,$email,etc)

Gambling Fever

Posted by Nessa | Posted in uncategorized | Posted on 22-02-2011

0

Before meeting my fiancé, the most exposure I’d had to gambling was the occasional friendly late night nickel/dime/quarter poker games you have with friends after a night of partying when you eventually get bored and have nothing else to do.  Well, that was then – nowadays I’m upping my housewife potential by learning how to do things like make laundry detergent and not blow up the microwave every time I want to make macaroni and cheese (you’re supposed to make that in the microwave, right?).  It would seem that at 23 I’m officially retired from having a life :)

My future mother-in-law got me into the casino scene the first time she brought us along on one of her frequent trips to Dover  Downs.  I was amazed at the concept of a slot machine: You put in $20, pull the lever a couple times, and while you may win a dollar here and there, suddenly it’s all gone. While you’re disappointed for a few minutes, you move onto the next machine and do the same thing, only to rinse and repeat until you’re out a couple hundred and heading to the ATM to get more.  All you hope for is that one shot of hitting a jackpot – after all, a couple hundred bucks is nothing compared to thousands that can possible fall in your lap, right?

…Riiiight. The last time I was in Dover I hit a winning streak at one of the high-roller Blackjack tables.  I was at the table for a few hours, and as the night wore on the table was joined by a young man that looked like a complete train wreck. His eyes were all red and watery as if he hadn’t slept in days, and he was nervously shuffling his chips on the table with one hand while his left leg was shaking under the table.  He was bidding $100 a hand  and every time he ran out of chips he’d disappear for a few minutes and come back with more.  After the third time he just sat in the chair as if he’d given up all hope in life.  Ironically, a few minutes later his wife called him and I overheard her on his phone asking him why their credit card was declined when she went to the store to buy diapers. Ouch.  That was when I picked up my winnings, cashed out, and went about enjoying the other amenities of the casino.   I’ m getting married soon and Richie and I have a specific three-year plan that consists of getting married, having a child, and purchasing our own house – a plan that can be easily foiled by excessive gambling debts.

Now for me, it’s easy to not get addicted to gambling because the nearest casino is four hours away.  As most of you know, I live in Virginia (a commonwealth), and there’s no way they’re going to legalize gambling anytime soon…so it’s not like I have to pass by a casino on my way to work every day.  After all, if Virginia ends up spending all their federal funding on gambling-related bankruptcies they won’t be able to spend $19 million to widen a road.

I leave you with the following pro gambling tips:

  • Only play with money that you are ok with losing
  • Only play with money you have – never take loans or cash advances from your credit cards
  • When you hit a winning streak and then inevitably start losing again, stop while you’re ahead
  • Don’t rely on gambling to supplement your income – at the most you’re probably going to end up breaking even in the log run (remember, winning a $2000 jackpot is nothing if you lost $500 a month for the last year trying to win it)
  • Instead of slots, try the card games – they require a little skill so it tends to be easier to win…
  • …but don’t play the computerized card games. They are totally rigged.
  • Give Poker Stars a try – you can download their little app and play poker online with real people (rather than the house) and, in addition to adding a little amusement to a lonely night, you’re likely to walk away with a couple extra bucks

Catching SoapClient Errors

Posted by Nessa | Posted in uncategorized | Posted on 01-02-2011

0

I recently wrote a PHP script that uses SoapClient to connect to a SOAP server to verify username/password credentials for a monitoring system.  The script basically returns the result as a yes or no – however, as we all know with SOAP, when you hit an error you get a mess of crap that comes back like this:

Uncaught SoapFault exception: [ERROR_BAD_LOGIN] Bad login or password. in /path/to/stuff.php:20

Stack trace:
#0 [internal function]: SoapClient->__call('GetAccountByNam...', Array)
#1 /path/to/stuff(20): Utils_SoapClient->GetAccountByName(Object(SoapVar))
#2 {main}

All I need is an error code, and when the SOAP function fails (which is expected if the login credentials are invalid), the script halts and I don’t get anything.  Luckily, PHP has pretty good exception handling that can tell SOAP to treat output like a test.   For example, the following line of code in the above example passes a username string ($struct) to a SOAP object, and is the line of code that is failing:

$result=$accountService->GetAccountByName(new SoapVar($struct, SOAP_ENC_OBJECT));
$result_username = $result->UserAccount->AccountId;

In my case, if the login credentials being tested are incorrect, the value of the $result variable should be empty.  To suppress the ugly SOAP error and only return what I want, I use exceptions:

try {
$result=$accountService->GetAccountByName(new SoapVar($struct, SOAP_ENC_OBJECT));
}
catch(SoapFault $result){
}
catch(Exception $result){
}

Therefore, I can now use the value of $result as intended:

if(!empty($result_username)){

echo "Login OK";
exit(0);
}else{

echo "Login failed";
exit(1);
}

One of Those “Ksplice Saved Our Asses” Moments

Posted by Nessa | Posted in uncategorized | Posted on 15-01-2011

3

There comes a time in every sysadmin’s life when you realize that as long as you have your job, you’re never going to

  1. have a life
  2. have friends
  3. sleep
  4. have a break from all the madness

When you fix server A, server B breaks. When you patch exploit 1, exploit 2 strikes threefold.  And to top it off, our customers are still using passwords like 123456.  Luckily, there’s someone out there that appears to be seeing things at my level.

We started using Ksplice back in September 2010 when one infamous kernel exploit started it all. We used to only have to do kernel updates a few times a year.  Now the RHEL guys decided to start compiling their kernels from sad pandas and french fries, backporting and reintroducing a string of security holes that hackers have been sitting until the opportune moment. When you’re working for one of the best hosts in the industry and basically guaranteeing 99.9% uptime, you try rebooting a dump truck full of servers five or six times a month just to avoid some asshat defacing all the index pages on your server with pictures of babies and swastikas.

I mean, unless you’re into that kind of thing.

During these unsexy times there’s one thing I’ve been continually grateful for – and that’s the fact that the developers of Ksplice apparently have no lives, girlfriends, or any other dreams in life other than to make all our jobs easier.  Here at IMH, we were all slightly depressed when we found out that we couldn’t have reboot parties anymore.  The Ksplice guys usually have new vendor-released kernel patches available within a day  and we can easily and instantly run kernel updates on our entire fleet of servers without having to reboot a single one.  With that, we don’t have to wait until the middle of the night over the span of several days to fix critical security problems, and customers don’t have to complain about downtime.  This lets us focus on what’s important: drinking, karaoke, and nude ice fishing keeping people happy.  If that’s not worth the $2.95 a month, I don’t know what is.

Simple Way to Parse an x509 Certificate with PHP

Posted by Nessa | Posted in uncategorized | Posted on 03-11-2010

4

PHP has a nifty little function for parsing an x.509 SSL certificate into an array to easily pull out the elements: openssl_x509_parse .Essentially, all you need to do is load up the contents of the certificate, either through a file or POST value, and enclose it in the array. Here’s a simple script:

<?php
$sslcert = file_get_contents("/etc/ssl/certs/secure.v-nessa.net");
$sslcert = array(openssl_x509_parse($sslcert,TRUE));
//print_r($sslcert);
foreach ($sslcert as $name => $arrays){
foreach ($arrays as $title => $value){
if(is_array($value)){
echo $value . "\n";
foreach($value as $subtitle => $subvalue){
echo $subtitle . " : " . $subvalue . "\n";
}
}else{
echo $title .  "\n";
}
}
}
?>

The results are several multidimensional arrays, so depending on the data you need, you may need to keep adding foreach loops to get that data.

Dear , It’s not your IP – Your Site Is Just…Unpopular

Posted by Nessa | Posted in uncategorized | Posted on 09-09-2010

2

At least twice a month I get an all so familiar request from hopeful customers looking to boost their Internet presence:

“Yea, I’m going to need about a bazillion IPs for all my sites. Oh, and they all need to be on different subnets. Ya know, SEO shit. I’m going to make it to the top”

…And at least twice a month I again have to explain why a dedicated IP address isn’t going to bump search engine rankings.

It’s a well-known fact that IPv4 space is running low. Being that there are over 180 million websites on the Internet (growing by the thousands every day), it eventually won’t be possible for every website to have its own IP. Additionally, ARIN now no longer accepts IP-based virtual hosting as justification for IP usage. In other words, unless you’re running a private anonymous FTP server, are using third party DNS services, or have an SSL certificate, you’re really not entitled to have your own IP. Though your hosting provider may still give you that option, they don’t have to if name-based Virtual Hosting (read: sharing IPs) is possible.

That being said, it doesn’t sound quite right that a search engine would punish your rankings for not doing something that isn’t feasible. Even if you don’t believe me, I’m sure you can believe one of Google’s software engineers who negated the fact that a dedicated IP will affect your pagerank.

If you’re seeing SEO success from one of your competitors, you can probably bet that it has little to do with their IP situation and more to do with them actually knowing what they are doing.  Plenty of sites have hit #1 in Google using old-school SEO techniques and marketing.  Your hosting provider is probably not going to give you half their IP allocation, so now that your entire belief system based around fake SEO techniques has been shot down, just don’t ask.

Review of ReclaiMe Data Recovery Software

Posted by Nessa | Posted in uncategorized | Posted on 05-08-2010

2

We all know how much it sucks to have a hard drive fail – months or even years worth of data down the drain. And I bet you don’t do regular backups, do you?

I came across ReclaiME from a review site. It’s software (that unfortunately only works on Windows) that you can install on your computer to reliably recover data from hard drives or memory cards.  More specifically, it lets you:

  • Recover images from a memory card
  • Recover data from flash/USB drives
  • Recover data from laptop, external, and SCSI/IDE drives
  • Unformat non-system drives and partitions

I actually ReclaiME on one of my sister’s old camera memory cards, and it definitely doesn’t fall short of its claims.   It recovered over 40 images from the almost-empty card, most of which were intact, though a few were corrupted from the camera overwriting them.

While the software is excellent and works just like it promises, the only downside is that the price is a bit steep for the average user.  I’d imagine that software like this would be more tangible for service providers, businesses, or people that consider their data valuable enough to justify spending a pretty penny on data recovery software.  The price isn’t outrageous or anything, it’s just more than I’d pay for Windows-based recovery software (I prefer to use Linux), when there are other free/open-source alternatives out there:

http://lifehacker.com/5237503/five-best-free-data-recovery-tools

Using PHP to Extract Image Exif Data

Posted by Nessa | Posted in uncategorized | Posted on 02-08-2010

19

Those of us fluent in digital photography have come across the term “Exif data” numerous times when it comes to software we use to digitally manipulate photographs. Exif (Exchangeable image file format) data is generally used to identify the properties of the camera that snapped a picture, and usually the software that altered it afterwards. It can tell you when a picture was taken, what kind of camera took it, as well as the camera’s model, shutter speed, focal length, and even provide a thumbnail of the image on the camera’s LCD screen.

Why would you need to extract this information?  If you’re ever uploaded images to stock photography sites and wonder how they know so much about your pictures, it’s because they extract the Exif data from your pictures to provide more information on how they were taken. This quick tutorial will demonstrate how to extract Exif data from an image using PHP.

Enabling the Exif Extension

The Exif functions for PHP may not be native to your installation, so you can check by viewing your phpinfo file or running “php -m” via command line to see a list of modules compiled in. If you don’t see Exif listed, there are three ways you can enable it depending on how you installed PHP:

  • If you compiled PHP manually, you can re-compile while adding –enable-exif to the configure line
  • If PHP is installed via package (rpm/deb), it should already have Exif enabled. If not, you can install an RPM for the extension manually
  • If you use cPanel, run EasyApache and select the Exif extension from the PHP module list, and recompile

Determining the Image Type

The exif_imagetype function identifies the format of an image, but returns the result as a code.  The PHP function reference provides a full list of these return codes, but 1-8 are the most common out of the 16:

1: GIF
2: JPEG
3: PNG
4: SWF
5: PSD
6: BMP
7/8: TIFF

Here’s a code example that lists all the desired valid image types in an array and detects the type of image from the specified file, returning the result in “human readable” format:

<?php
$image = "/path/to/myimage";

$types = array(
1 => "GIF",
2 => "JPEG",
3 => "PNG",
4 => "SWF",
5 => "PSD",
6 => "BMP",
7 => "TIFF",
8 => "TIFF"
);

$imagetype = exif_imagetype($image);

if (array_key_exists($imagetype, $types)) {
echo "Image type is: " . $types[$imagetype];
} else {
echo "Not a valid image type";
}
?>

Reading Exif Header Data

The exif_read_data function can be used to extract header data from JPEG and TIFF files:

<?php
$image = "/path/to/myimage";
$exif = exif_read_data($image, 0, true);
foreach ($exif as $key => $section) {
foreach ($section as $name => $val) {
echo "$key.$name: $val\n";
}
}
?>

This will return the elements of the array from exif_read_data, which can be very long depending on what information is available for the image. There are seven sections (arrays) of data types:

  • FILE:  Contains the file’s name, size, timestamp, and what other sections were found (as listed below)
  • COMPUTED: Contains the actual attributes of the image
  • ANY_TAG:  Any information that is tagged
  • IFD0:  Mostly contains information about the camera itself, the software used to edit the image, when it was last modified, etc
  • THUMBNAIL: Information about the embedded thumbnail for the image
  • COMMENT: Comment headers for JPEG images
  • EXIF: Contains more information supplementary to what is in IFD0, mostly related to the camera (includes focal length, zoom ratio, etc)

Depending on the information available for the image, you’ll actually see a lot of data in the output. Say, for instance, you want to only output the IFD0 data to see the information of the camera that took the image:

<?php
$image = "image.jpg";
$exif = exif_read_data($image, 0, true);

foreach ($exif as $key => $section) {
foreach ($section as $name => $val) {
if($key == "IFD0"){
echo "$key.$name: $val\n";
}
}
}
?>

This will output:

IFD0.ImageWidth: 2592
IFD0.ImageLength: 3872
IFD0.BitsPerSample: Array
IFD0.Compression: 1
IFD0.PhotometricInterpretation: 2
IFD0.Make: NIKON CORPORATION
IFD0.Model: NIKON D80
IFD0.Orientation: 1
IFD0.UndefinedTag:0x0000:
IFD0.XResolution: 72/10000
IFD0.YResolution: 72/1
IFD0.PlanarConfiguration: 1
IFD0.ResolutionUnit: 2
IFD0.Software: Adobe Photoshop CS4 Windows
IFD0.DateTime: 2010:02:06 22:24:09
IFD0.Exif_IFD_Pointer: 304

Or, you can further narrow down the output by specifying specific values in the $exif multi-dimensional array:

<?php
$image = "image.jpg";
$exif = exif_read_data($image, 0, true);
echo "Software: " . $exif['IFD0']['Software'] . "\n";
?>

This will return:

Software: Adobe Photoshop CS4 Windows

Using Exif to generate a thumbnail

As touched on previously, many cameras and image manipulation software will include an embedded thumbnail for an image. You can extract this thumbnail using the exif_thumbnail function:

<?php
$image = "image.jpg";
$thumbnail = exif_thumbnail($image, $width, $height, $type);
echo "<img  width='$width' height='$height' src='data:image;base64,".base64_encode($thumbnail)."'>";
?>

Keep in mind that the thumbnail generated here is from the Exif data – there are other ways to create a thumbnails using many of the PHP image functions.