Howto: Create and Stream a CSV with PHP

I find myself constantly creating csv files for users to download. Whether it’s a method for users to export their data to excel, a way for users to backup their hosted data, or just a simple way to send them report information, csv files are extremely useful. Normally I just create an actual file and link to it for the user to download. The files are usually cleaned up after a certain amount of time or after a certain number of newer files exist.

Recently however, I had a client that really wanted to be able to export data in csv format without ever creating a file on the webserver. Their concern was rooted in security, but the reality of the matter was that they were trying to obey the letter of the law with regards to company policies. Whether it was truly necessary or not is for another discussion. Instead, the technique is actually very useful so I thought I’d share.

The key to this is that the fopen function supports php input/output streams as wrappers.

Read more

Can open source eCommerce contend?

It seems that sometimes work comes in waves. I haven’t dealt with setting up a shopping cart on a site in quite a while, and now I have three clients that I’m setting up shopping carts for. The clients want a PHP based solution (good thing, considering that’s what I do), and as usual the less we spend the better. I started by looking at the available FOSS options, fully expecting that this would be a simple task. Little did I know…

The first application I looked into was osCommerce. The best way I can describe it is as an old dragon. It may be free and open source, but it’s big, bulky, and outdated. I was looking for something much easier to use, and much more current. Something that would be easy to manage once it was set up, as opposed to taking two hours to add color options to a product.

Not to be discouraged, I moved on another possibility, zenCart. ZenCart is a huge step in the right direction, but it still seemed to lack the intuitive interface that you might expect from web based software. I may be too hard on them, but a quality user interface makes the difference between happy customers, and customers that never return. All in all, there is a lot of really great technology which zenCart doesn’t use, and while it’s free and open source, that doesn’t make up for it’s lack of usability.

I continued to look around at free alternatives, but didn’t find anything noteworthy. Now I was discouraged. I decided to check into some commercial products, most notably cubeCart. It costs $130 – $180 and it’s not 100% open source, but cubeCart makes up for all that with the interface. It has an intuitive admin section, better support, and plenty of available add-on modules (for shipping, payment, even affiliate programs). In the end, we went with cubeCart, deciding that the benefits were worth the cost. I was almost ready to admit that the available FOSS options couldn’t touch commercial products in this market. Just then, a glimmer of hope! Magento.

Magento is a new up and coming PHP shopping cart, built using the Zend Framework. It is young and currently still in beta, but it shows great promise. According to their roadmap, the production version is due out first quarter 2008. It’s current drawbacks are it’s lack of support for certain payment and shipping gateways, and it’s lack of support for popular affiliate programs. However, much of this is in the roadmap, and should make it into the production version. In my experience, what they currently have out is stable, and extremely user friendly. I can finally breathe a sigh of relief, knowing that there will soon be a FOSS option that will be able to compete with their commercial counterparts.

In the end, if you need something right now, cubeCart is for you. While it will require some up front investment, you will save it back just on the Tylenol you won’t be buying for the headaches you will have with osCommerce or zenCart. However, if you don’t need something for a few months, or you are trying to keep an eye to the future, check out magento. You’ll be glad you did.

PHP function to Redirect a user with a message

One of the common things that you need to do in PHP is redirect a user, and display a message on whatever page you are sending them to. There are a lot of reasons for this, but the most common is to avoid a user refresh from resubmitting a form. Instead, process the form data, and redirect the user (even if you redirect them to the same page). Here is a function I use for this very purpose. It requires that you are using sessions. It stores the message in the session, and passes a has in the URL. This way, you can use any length message you want, and display it only once.
Read more

Replace every other occurrence with str_replace

Well, someone put some code onto the str_replace PHP manual page to replace every other occurrence of a string with another string. However, it didn’t work, and was simply spam to get a link onto the PHP manual page (shame on them). So I made a function that DID work, for the poor lost souls who would be trying over and over to make that one work. I figured that since I made it, I might as well post it, maybe someone needs something like this.

/**
* Replaces every other occurrence of search in haystack with replace
*
* @param $needle mixed
* @param $replace mixed
* @param $haystack mixed
* @param $count int[optional]
* @param $replace_first bool[optional] - Default true
* @return mixed
*/
function str_replace_every_other($needle, $replace, $haystack, &$count=null, $replace_first=true) {
    $count = 0;
    $offset = strpos($haystack, $needle);
    //If we don't replace the first, go ahead and skip it
    if (!$replace_first) {
        $offset += strlen($needle);
        $offset = strpos($haystack, $needle, $offset);
    }
    while ($offset !== false) {
        $haystack = substr_replace($haystack, $replace, $offset, strlen($needle));
        $count++;
        $offset += strlen($replace);
        $offset = strpos($haystack, $needle, $offset);
        if ($offset !== false) {
            $offset += strlen($needle);
            $offset = strpos($haystack, $needle, $offset);
        }
    }
    return $haystack;
}

//Use it like this:
$str = "one two one two one two";
echo str_replace_every_other('one', 'two', $str, $count).'\r\n';
//two two one two two two
echo str_replace_every_other('one', 'two', $str, $count, false).'\r\n';
//one two two two one two

I added the last option ($replace_first) to let you replace the odd occurrences (true, default) or the evens (false).

PHP Pagination with mysqli

I’m asked pretty regularly for help with pagination in PHP. I have a nice mysqli pagination class that I use. Once it’s implemented, it is used like this:

/**
* $db is your mysqli connection
* $query is your query
* 'mailPage' is the $_GET variable to use for the pages.  It defaults to 'page' but using different values lets you have separate
* paginated data on that same web page.  Setting multiple paginated items on the same webpage to the same "page" variable
* will mean that when one goes to page two, all of them go to page 2.
*/
// Require the class
require_once('paginate.class.php');
// Lets not use your normal SELECT * FROM table query...just to show it still works
$query = <<<
    SELECT
        `mail`.`id`,
        `mail2`.`read`,
        `mail2`.`seen`,
        `mail`.`from`,
        `mail`.`sent`,
        `mail`.`subject`,
        `mail`.`body`,
        `users`.`full_name` as from_name
    FROM `mail`
    JOIN `users`
        ON (`mail`.`from` = `users`.`id`)
    JOIN `mail2`
        ON (`mail`.`id` = `mail2`.`mess_id`)
    WHERE
        `mail2`.`uid`=1 &&
        `mail2`.`folder`=1
    ORDER BY
        `mail`.`sent` DESC
EOQ;

// Create our paginate object, and pass it the database, query, and page var
$paginate = new Paginate($db, $query, 'mailPage');
// Run the query
$r = $paginate->get_results();

// Loop through our results
while ($message = $r->fetch_object()) {
// Create your page of information
}

// Show the page links
echo $paginate->show_pages();

Read more