Archive for category PHP

Send email attachment with PHP

Everybody probably knows how to send an email using PHP, but do you know how to send an email with an attachment?

This is actually not very difficult and you can find examples all over the web. However, it seems that all the examples I found didn’t work! 🙁
But after some debugging and testing, I finally got a working solution. 😀

Please see below the code with comments:

// Define some variables
$to = 'test@logikdev.com'
$subject = 'Test email';
// Create a boundary string. It must be unique so we use the MD5 algorithm to generate a random hash
$random_hash = md5(date('r', time()));

// Define the headers
$headers = "From: noreply@logikdev.com\r\n";
// Add boundary string and mime type specification
$headers .= "Content-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"";

// Read the attachment file contents into a string, encode it with MIME base64, and split it into smaller chunks
$attachment = chunk_split(base64_encode(file_get_contents('attachment.zip')));

// Define the body of the message
$message = "
--PHP-mixed-$random_hash
Content-Type: text/plain; charset='iso-8859-1'

This is a test email message sent with PHP.

--PHP-mixed-$random_hash
Content-Type: application/zip; name=attachment.zip
Content-Transfer-Encoding: base64
Content-Disposition: attachment

$attachment
--PHP-mixed-$random_hash--";

// Send the email
if (@mail($to, $subject, $message, $headers)) {
	echo "The mail has been sent.";
} else {
	echo "The mail has NOT been sent!";
}

, ,

3 Comments

Segmentation fault at end of PHP script

This one is a very strange problem!
I created a little PHP script which connects to a MySQL database. Nothing amazing, except that I needed to run it via command line using the php command. What happened is that the script ran perfectly fine but, for some reason, it returned “Segmentation fault” when it reached the end of the file! 😯
It reminds me of the old days when I worked on C language, I used to see this not-very-useful message quite often. 😉

Anyway, why do we get a “Segmentation fault” at the end of a PHP script? And when I say ‘the end’, I mean after any other lines!

Looking around the web, I found the following bug report: http://bugs.php.net/bug.php?id=43823
This user seems to have the same problem than me except he is using a PostgreSQL database instead of a MySQL database.

Reading through the page, it looks like the problem comes from the order in which PHP loads his extensions! They explain that PostgreSQL should be loaded before cURL. If I apply the same logic, MySQL should then be loaded before cURL too.

To do that, we need to comment out the line extension=curl.so from the file /etc/php5/cli/conf.d/curl.ini:

# configuration for php CURL module
#extension=curl.so

And add it to the file /etc/php5/cli/conf.d/mysql.ini AFTER the line extension=mysql.so:

# configuration for php MySQL module
extension=mysql.so
extension=curl.so

To be honest, I don’t really like this solution as it is a bit messy. I would prefer PHP developers to fix the root cause or at least have a way to change the order in which PHP loads the extensions.

NB: I was executing this PHP script on a Debian GNU/Linux 5.0 with Apache 2.2.9 and PHP 5.2.6.

, , , , , ,

1 Comment

Encrypt with PHP – Decrypt with Java

For security reason, I wanted to encrypt the data transferred between PHP web services and a Java application. But the problem was to encrypt the data with PHP in a way that it is possible to decrypt it using Java.

It obviously exists a lot of ways of doing this. But here is the way I choose:

  • Use a secret key and an initialisation vector for the encryption and decryption
  • Use the mcrypt PHP module for the encryption
  • Use the javax.crypto Java package for the decryption

Please find below the PHP code for the encryption:

function encrypt($message, $initialVector, $secretKey) {
    return base64_encode(
        mcrypt_encrypt( 
            MCRYPT_RIJNDAEL_128,
            md5($secretKey),
            $message,  
            MCRYPT_MODE_CFB,
            $initialVector
        )
    );
}

And please see below the Java code for the decryption:

public static String md5(String input) throws NoSuchAlgorithmException {
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] messageDigest = md.digest(input.getBytes());
    BigInteger number = new BigInteger(1, messageDigest);
    return number.toString(16);
}

public String decrypt(String encryptedData, String initialVectorString, String secretKey) {
    String decryptedData = null;
    try {
        SecretKeySpec skeySpec = new SecretKeySpec(md5(secretKey).getBytes(), "AES");
        IvParameterSpec initialVector = new IvParameterSpec(initialVectorString.getBytes());
        Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, initialVector);
        byte[] encryptedByteArray = (new org.apache.commons.codec.binary.Base64()).decode(encryptedData.getBytes());
        byte[] decryptedByteArray = cipher.doFinal(encryptedByteArray);
        decryptedData = new String(decryptedByteArray, "UTF8");
    } catch (Exception e) {
        LOGGER.debug("Problem decrypting the data", e);
    }
    return decryptedData;
}

EDIT: The line number.toString(16) of the md5 method needs to be replaced by String.format("%032x", number). See this article for more details.

, , , , ,

45 Comments