Tag: PHP

Tail In PHP

December 3, 2010 » Geek

So I’m working on a little admin interface and I decided to tail some logs. It’s in PHP and Google came up with some stuff, but they were all a bit finickey and not well documented. So I wrote my own!

Here’s the basic concept:

  1. Open File
  2. Seek To End
  3. Loop:
    1. Seek Back By Chunk Size
    2. Read Chunk
    3. Count Newlines
    4. Stash In Buffer
    5. Break If Enough Newlines Total
  4. Trim Extra Line & Cruft
  5. Done!

Here’s the code:

You can give it a try on some junk data here: http://static.velvetcache.org/pages/2010/12/03/tail-in-php/

Premature optimization is the root of all evil. But don’t be stupid.

August 2, 2010 » Geek

There is a relatively prevalent quote in the programming world, bandied about by programmers of all creeds.

“Premature optimization is the root of all evil.”

– Donald Knuth

I agree. What we intuit about optimization is usually wrong. And what’s more, until you hit a bottleneck, it’s often a waste of time. Moore has been good to us, and CPU bound problems aren’t as common as they once were.

That said, I think people should not cling to this. It’s dumb.

Today I was looking for a better way to compute sha1 file hashes in PHP. I know about sha1() obviously, but that’s not how it should be done for files.

Python provides the excellent hashlib that lets you update a hash with blocks of data. It’s excellent for file hashing, because you can read in data in chunks and update the hash as you go, thus avoiding reading the whole file into memory at once. Here, have a sample program that reads in 512 byte chunks.

So I quickly found the sha1_file() function. Perfect, I’m sure this reads in chunks, otherwise they would not have bothered to make the function.

Then I scroll down to check the user contributed notes for anything interesting. The top two notes are examples of using this snippet to get a sha1 hash of a file:

I was stunned. The definition of file_get_contents() is as follows:

“Reads entire file into a string.”

Surely they are not suggesting that I read the entire file into memory, as a PHP variable, and then pass it on to the hashing function? Who would think that is a good solution, when there is a perfectly good built in function to do this for you, in chunks, in a neater fashion?

My only explanation is ignorance, or utter lack of consideration. I gave it a test with these two PHP scripts.

The first version weighed in as using slightly more memory than second one. About 89k actually. And test.jpg is 88k.

Imagine if that picture was a few megs bigger. Imagine if I could somehow trigger this process on your website, over and over again with ab or something. It’s a DOS in the making.

Develop however you want to, just please, please don’t be stupid.

Charting Weight Change With Google Visualizations

July 5, 2010 » Consume, Geek, Life

I started trying to lose weight a while back, since we both know I’m a bit heavy and sitting in front of a computer isn’t going to lose the weight for me.

Naturally, it’s important that I incorporate technology into my weight loss somehow, right? So I decided to give the Google Visualizations API a spin.

I worked up a quick data format and a method to pop the data out. Nothing fancy, just a fixed width flat file. This doesn’t deserve a database.

Easy to read, easy to edit, and easy to consume. Every morning I just hop on the server, add the day’s weight and log off.

Now I just needed to represent it. The API is very object oriented and easy to work with. I wish there was a less verbose way of presenting the data, but you can’t have everything.

Actually, there may be a better way, I just didn’t come across it while speed reading the docs.

And there you have it, fancy charting in no time.

Example Chart

See it in action at http://static.velvetcache.org/weight.php

Get the full source at http://gist.github.com/459148.

PHPainfree Test Drive

June 7, 2010 » Consume, Geek

What is PHPainfree

PHPainfree is a relatively young PHP framework written by Eric Ryan Harrison.

The README for the project is in first person, so I’ll let PHPainfree explain what it is:

I am an ultra-lightweight PHP framework. I am inspired by the MVC concept, but I’m too artsy to let myself be defined by labels like that. I basically do what I want.

Installation

To try the framework out I cloned the git repository. This should be roughly equivalent to version 0.6.3, in case you want to follow along at home.

My setup is a bit unique, as a trial usage in a sub-directory of my local machine, but you should be able to adjust your install to suit.

It essentially boiled down to these steps:

  1. Clone Repository
  2. Edit includes/PainfreeConfig.php
  3. Symlink includes/ and templates/ into htdocs/
  4. Tweak RewriteBase in htdocs/.htaccess

Shell Transcript

Listing: htdocs/.htaccess

After that is all done, it should happily serve up it’s welcome page.

It Works!
It Works!

Framework Basics

When PHPainfree claim’s to be ultra-lightweight, they mean it. Many of the bits and pieces you would expect on a framework just don’t exist. Many.

But more on that later. For now, let’s take apart the default files and build something out of them. What we’ll attempt to assemble is that paragon of beginner programs, the todo list.

Looking at the provided example files it really seems to me that this is a very view driven framework. The “logic” part runs first, but really just sets up things for the “view” part. Model and controller seem smashed together into the “logic” files, but this is just my interpretation of the design.

This is how the provided example files flow:

Getting Started

BaseView

According to includes/PainfreeConfig.php the BaseView “is the name of your base template inside of the templates folder. This base view generally provides the overall framework of output for your application”.

To feel out how the framework handles I created a very small stub BaseView in templates/layout.tpl

Listing: templates/layout.tpl

ApplicationController

According to includes/PainfreeConfig.php the ApplicationController is “…the primary controller for your application”.

I created a new controller for my test, taken almost entirely from the provided includes/Generic.php.

Listing: includes/ToDoList.php

PainfreeConfig

The last step for this first exploratory version is to change some variables in our configuration file.

Listing: includes/PainfreeConfig.php

Once that is done, it should now be serving my new files.

Exciting

Building The Application

That’s great and all, and we learned about the processing pipeline and stuff, but really, we didn’t do anything.

So let’s get down to it. I like a nice MVC pattern, with convention over configuration, so here is how I’m laying out my application. Note that you do not have to do it this way, PHPainfree is written to encourage you to do it, well, just about any way you want.

Routing Requests

To make my structure work, I had to create my own routing system. I couldn’t find anything built into PHPainfree that would do this for me, but that’s okay because it’s pretty simple. I set my ApplicationController option to “main.php” and placed this in there.

Listing: includes/main.php

BaseController

Note that on line 18 I instantiate a class called BaseController. This is a stub class that I created for all of my controllers to inherit from, that way I have a consistent interface to call in my templates.

My BaseController.php file will be placed into includes/Autoload to take advantage of the loading feature of PHPainfree. Any file placed into the includes/Autoload folder will be automatically included at runtime, just after the configuration file is loaded and just before the logic file is ran. This is useful for loading libraries, or to do some request pre-processing.

Listing: includes/Autoload/BaseController.php

The Database

Up to this point I haven’t touched a database, which PHPainfree has some support for. Real quick I’ll set up a MySQL database for our ToDo application.

MySQL Transcript

Configuring The Database

Configuring the database connection in PHPainfree is relatively straightforward. Just open up includes/PainfreeConfig.php and find the Database key. This is an array of MySQL connections, which cascade if they fail.

For instance, if you have a development environment and a production environment, you could place your dev configuration after the production configuration.

In development, the production connection would fail and then load the development configuration. Nothing to change, no environment variables to set, it just works.

Listing: includes/PainfreeConfig.php

Using The Database

Using the database is easy too. The $Painfree global variable has a member called db which provides access to our configured database. But what is $Painfree->db? Well, a little bit of digging into the PHPainfree core and we find out it is just a normal MySQLi link object. Nothing fancy, no database abstractions.

Listing: includes/core/DBD/mysql.php

Bringing It Together

Applying all this knowledge and configuration, let’s start our first controller, the List_Controller. This first version will simply fetch all the active lists from the database and get them ready for the template.

Listing: includes/controllers/list.php

Now we need to make our template to use this controller. Again, very basic.

Listing: templates/list/index.tpl

At this point, we should be able to render this view:

A List of Lists
A List of Lists

Finishing Up

From here it is a short work to finish the application with another controller and a few more actions. Rather than post a bunch of reptitive code snippets I’ll provide my completed source, here.

A List of ToDo's
A List of ToDo’s

Conclusions

So, there is my first PHPainfree application. As with any new tool, my usage is probably flawed until I learn more about it. So take this review with a grain of salt.

Con’s

PHPainfree is a young framework, and it’s a thin one. Coming from a heavier framework background, it feels too thin to me. I missed having an ORM, and built in helpers (think Form, Link, Validation). Also, there is no real exception stack that I could find, just $Painfree->debug() for you to use.

MySQL is the only option right now, though it is easily extended. For example, I wrote this in just a few seconds to add SQLite3 support.

Listing: includes/core/DBD/sqlite.php

However, having multiple drivers is shallow when there is no abstraction element. Since it uses native driver objects, I can’t just switch from MySQL to SQLite3, because I would then have to switch all of my method calls. Using PDO would be a good option for PHPainfree, IMHO.

My other qualm is the rendering stream. I’m used to the standard MVC pattern, where the controller fetches data with models and publishes it via views. There may be a way to work like that in PHPainfree, but it’s not readily apparent.

Pro’s

It’s light, at the cost of including minimal features. And it’s fairly easy to understand. According to SLOCCount there are only 101 lines of source (after removing the config file and default controller). You can read the whole framework in a few minutes.

Really, I think this is a framework to build your own framework. The core idea of PHPainfree is to stay out of your way. If I intended to use PHPainfree on a regular basis, I would set it up the way I like it, dumping libraries into includes/Autoload and then keep a tracking version in git with all my addons.

Finally…

I think that where you can draw the most value from this framework is building something you love on top of this common core code. So give it a try at http://github.com/februaryfalling/PHPainfree

Bin2Img: Data Visualization with PHP

March 15, 2010 » Geek

Update (2010-03-15)
I added some more examples at the bottom of the post.

I’ve been toying with random numbers recently (more on that another day), and one of the things I wanted to do was find a way to visualize the bits I was generating. The simplest way I could think of is a big bitmap, with each pixel representing a bit and a 0 being white while a 1 is black.

This is an example output of what I came up with, it’s a sample run of the first MB of a zip I had laying around. I recommend a click through for the full sized version, it got blurry when I downscaled it.

black and white dots...

I chose PHP for the task as I didn’t have the time or energy to learn an API in any other language, and I already knew the PHP commands. Here is the source for your perusal. The only tricky bit is accurately reading a byte of raw binary data from file (pro-tip: unpack is essential).

Here are some more data sets:

black and white dots...
1Mb from /dev/urandom
dd if=/dev/urandom of=data.bin bs=1kB count=1024

black and white dots...
Digits of Pi (as characters)
Data file from here run trough the following to remove newlines and spaces.
cat pi.bin | tr -d ' ' | tr -d '\n' > data.bin

black and white dots...
This photo of a peep spider

black and white dots...
2008 Early Release Toxics Release Inventory data for the state of California
Windows exe from Data.gov