A Programmer’s Perspective twitter
A Programmer’s Perspective Rss

PHP File Streaming with cat and passthru

Posted by Jason | Posted in linux, mysql, php | Posted on 09-11-2009

3

The problem

This weekend, I needed to figure out how to make an on-request, downloadable, backup of an entire MySQL database (for Magento, in case you were wondering).
At first, I attempted the simplest approach, which was to perform the backup via system() or exec(), and then serve the file as a download using either file_get_contents or fopen/fread, etc. This wouldn’t work because PHP would run out of memory when reading the file. I even tried stream_get_contents() with the same result.

Hmmm….

I’m sure there are other ways of getting this done, but my approach has been working flawlessly so far and I thought I’d share with you.

The solution

Here is the entire code segment which performs the backup, bzips the SQL file, then serves it as a download using passthru and cat.


//Define where backup will go
$backup_folder = getenv("DOCUMENT_ROOT") . $settings['base_url'] . '/backup/';
$backup_file = 'aps_backup_' . date("Y-m-d-H-i-s") . '.sql.bz2';
$backupFile = $backup_folder . $backup_file;

//Perform the database backup
$command = "mysqldump --opt -h$dbhost -u$dbuser -p$dbpass $dbname | bzip2 > $backupFile";
error_log("Executing: $command");
exec($command);

//Serve file as download
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$backup_file\"");
passthru("cat $backupFile");

As you can see, the database backup command is executed, and the output is bzipped and stored in the “backup” folder.
Once the command is completed, the headers are setup to serve a file download, and using the passthru command, we simply cat the file.
This effectively streams the file as a download, thus alleviating the memory limit errors I was receiving when trying to open/read/serve the large file download.
Obviously, this wouldn’t work on Windows.

I’m curious if anyone else has been faced with this problem, and what your solution(s) were?

PHPMailer Inline String Attachment

Posted by Jason | Posted in mysql, php | Posted on 09-09-2009

1

Recently, while using PHPMailer, I needed the ability to have an inline string attachment, however this functionality is not present as of version 5.0.2, so I wrote my own.

For those who don’t know, PHPMailer has a number of ways you can create email attachments:

  • Standard Attachment – works as you’d expect
  • Inline Attachment – attachments you can reference in the message body. For instance, if you attach an image, you can then reference that image using the IMG tag in the body
  • String Attachment – builds an attachment from blob data (usually stored in a database)

Inline attachments and String attachments rock, however there was no combination of the two. So, I wrote one. Simply add this block of code to your phpmailer class and you’re good to go.


/**
* Adds a string or binary attachment (non-filesystem) to the list.
* This method can be used to attach ascii or binary data,
* such as a BLOB record from a database.
* @param string $string String attachment data.
* @param string $cid Content ID of the attachment. Use this to identify
* the Id for accessing the image in an HTML form.
* @param string $filename Name of the attachment.
* @param string $encoding File encoding (see $Encoding).
* @param string $type File extension (MIME) type.
* @return void
*/
public function AddInlineStringAttachment($string, $cid, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
// Append to $attachment array
$this->attachment[] = array(
0 => $string,
1 => $filename,
2 => $filename,
3 => $encoding,
4 => $type,
5 => true, // isStringAttachment
6 => 'inline',
7 => $cid
);
}

Kaltura Wordpress Plugin – Switching Partner IDs

Posted by Jason | Posted in mysql, php | Posted on 26-05-2009

0

I am using the Kaltura All-In-One-Video Wordpress Plugin on a project these days and I’ve come across a situation where I needed to switch my Partner ID to a new one (we purchased a paid account).

However, there is currently no way of doing this in the interface or by editing any of the plugin files… weird.

After calling their support and getting no answer, I found my own solution and I’m posting it here in hopes that it may help you.

This involves deleting a few rows from the wordpress database, so I’d recommend doing a backup before any of this.

Simply running the following SQL statement on your wordpress database will remove all Kaltura configurations:

delete from wp_options WHERE option_name LIKE ‘kaltura%’;

After running this statement, login to the admin area of Wordpress and you will now be prompted to Create a Partner ID (or specify an existing one).

Hope this helps!