Categories
How-To WebApps

How to Make Your Own PHP Extension… Quick and Dirty

This is a cheat sheet on how to extend PHP. I’m learning how to fix bugs in C within the PHP source code right now using what’s google-able, the #php chat room in irc.freenode.net and “Extending and Embedding PHP” by Sara Goleman.

Preliminaries: make sure you have the right tools for building php from source. Right now these tools are:

  • autoconf: 2.13
  • automake: 1.4+
  • libtool: 1.4.x+ (except 1.4.2)
  • bison: 1.28, 1.35, 1.75, 2.0 or higher
  • flex: 2.5.4 (not higher)
  • re2c: 0.9.11+ (0.12.0+ for HEAD)
  • Get the latest php stable version. as of this blog posting it’s php-5.2.6
  • unpack the file using something like bunzip2 -c < php-5.2.6.tar.bz2 | tar xvf -
  • ./configure –prefix=/usr/local –enable-debug (I’m really old school and like to put my stuff in /usr/local . YMMV.)
  • make ; make install

If that worked now we’re ready to make a module. Feel free to substitute barce or BARCE in the code below with whatever you want the module name to be.

  • cd ext (if you type ls you’ll see the extensions that come with php.)
  • mkdir barce (I’m a narcissistic, buddhist, nihilist.)
  • create a config.m4 file with this code:
PHP_ARG_ENABLE(barce,
        [Whether to enable the "barce" extension],
        [  --enable-barce       Enable "barce" extension support])

if test $PHP_BARCE != "no"; then
        PHP_SUBST(BARCE_SHARED_LIBADD)
        PHP_NEW_EXTENSION(barce, barce.c, $ext_shared)
fi
  • then create a php_barce.h file:
#ifndef PHP_BARCE_H
/* Prevent double inclusion */
#define PHP_BARCE_H

/* Define extension properties */
#define PHP_BARCE_EXTNAME "barce"
#define PHP_BARCE_EXTVER "1.0"

/* Import configure options
 * when building outside of the 
 * PHP source tree */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/* Include PHP standard Header */
#include "php.h"
/*
 * define the entry point symbole
 * Zend will use when loading this module
 */
extern zend_module_entry barce_module_entry;
#define phpext_barce_ptr &barce_module_entry

#endif /* PHP_BARCE_H */

  • create a barce.c file with your functions that you are creating for PHP
#include "php_barce.h"

PHP_FUNCTION(barce_thinks_youre_cool)
{
        char *name;
        int name_len;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", 
                &name, &name_len) == FAILURE)
        {
                RETURN_NULL();
        }

        php_printf("Barce thinks you're cool, ");
        PHPWRITE(name, name_len);
        php_printf("!\n");
}


static function_entry php_barce_functions[] = {
        PHP_FE(barce_thinks_youre_cool, NULL)
        { NULL, NULL, NULL }
};

zend_module_entry barce_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
        STANDARD_MODULE_HEADER,
#endif
        PHP_BARCE_EXTNAME,
        php_barce_functions, /* Functions */
        NULL, /* MINIT */
        NULL, /* MSHUTDOWN */
        NULL, /* RINIT */
        NULL, /* RSHUTDOWN */
        NULL, /* MINFO */
#if ZEND_MODULE_API_NO >= 20010901
        PHP_BARCE_EXTVER,
#endif
        STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_BARCE
ZEND_GET_MODULE(barce)
#endif

Now let’s build this puppy.

  • phpize
  • ./configure –enable-barce
  • make
  • there should now be a modules directory. copy it to /usr/local/lib/php/modules/ .
  • edit php.ini and add two lines:
    • extension_dir = “/usr/local/lib/php/modules”
    • extension = “barce.so”

Let’s test and see if it worked:

php -r “barce_thinks_youre_cool(‘Put your name here’);”

Categories
How-To TechBiz WebApps

The Code of Successful Websites

Hypothesis:

Coding is a free market enterprise. Wild-west coding or coding anarchy is more profitable and more likely to encourage progress than following any coding methodology. (I.e. waterfall, agile, extreme, pair coding, etc.)

I. This is shown by the source code of the most successful companies. The only commonality they share is that their most popular product feature was born of a non-methodological hack. It is only after the initial phase of success that a company brings order to the code.

II. The code that brings a company its first success is un-readable and un-maintainble.

III. Coding profitably is a result of breaking the rules and letting the market rather than the development process decide. Web analytics is vital.

IV. The consistency condition that demands coders code according to a design pattern or for the sake of maintainability is unreasonable because it either preserves an unprofitable coding methodology or obscures money making logic in the guise of readable code.

V. There is no coding method or technology however absurd or ancient that cannot be profitable. (My Space running on Cold Fusion w/SQL Servers as a back end.)

VI. There exists no code base that is capable of generating profit that is 100% in harmony with a given coding methodology. Many code bases are constituted by older technologies and older ways of making money; therefore a clash between methodologies is a sign of being wise and sensitive to changing markets.

Categories
How-To TechBiz WebApps

Migrating to the Newest Youtube API

You’ve got until August 30th, 2008 to migrate your code to the latest Youtube API. After that date, your current code base might not work.

I used 3 important coding concepts while working on migrating my Youtube Facebook App to the newest Youtube API:

Youtube

The strategy pattern allows you to define common behaviors that will be shared among your set of classes. In this case, I’ve got a class for the old Youtube API, and a class for the new Youtube API. Although the URLs used for accessing the two APIs are different, I’ll define a method common to each class for accessing URLs. In this case it’s the setURL method.

In PHP I do this like so:


interface apiCalls
{

public function setUrl();

}

The factory pattern allows me to create an instance of an object for using the old API or the new API on the fly. Factory methods just return the new instance of an object.

$dynamic_fave = FaveFactory::Create(“cyphgenic”, ‘yes’, 2, ‘on’, ‘2.0’);
$dynamic_fave->setUrl();
print $dynamic_fave->url . “\n”;

$dynamic_fave = FaveFactory::Create(“cyphgenic”, ‘yes’, 2, ‘on’, ‘1.0’);
$dynamic_fave->setUrl();
print $dynamic_fave->url . “\n”;

If you take a look at the code I’ve got and compare the old version with the new one, you can also see that I’ve cleaned up the nested if-else statements with arrays.

BAD NESTED IF-ELSE:

      if ($showUploaded == 'on') {
        $method   = "youtube.videos.list_by_user";
      } else {
        $method   = "youtube.users.list_favorite_videos";
      }

YAY! NO IF-ELSE:

      $h_method['on'] = "youtube.videos.list_by_user";
      $h_method['off'] = "youtube.videos.list_by_user";
      $method = $h_method[$this->showUploaded];

Below are the links to the bits of the code that I had to migrate. I just use one particular method, setUrl() as an example.

You might be wondering why two classes for the old and new API. If any new features need to be coded, or bugs need to be fixed in either API, I can do so within a particular class, and not add more obfuscation to the code. The two classes don’t violate the DRY principle because each models a particular thing.

Categories
How-To TechBiz

Quick follow up on JS-Kit

You can now snag ratings pretty easily. I got this from Lev Walkin who works at js-kit. Here’s an example:

http://js-kit.com/rating-data.js?
ref=http%3A%2F%2Fwww.cyphgen.com&p[0]=/&jx[0]=0

The first param in the query string is your site URL put through a url-encoder. The 2nd param p[0] is the path to the thing you are rating. In this case just the home page.

I hope this helps and thanks again, Lev and the folks at js-kit.com

Categories
How-To TechBiz

Stealing Your Js-kit Ratings for Fun and Profit with Ajax

Want to steal your js-kit data back now? Get the source.

Keep reading if you want to learn more about getting your data if it’s hidden in Javascript and can’t be scraped.

TechCrunch enthusiastically blogged about Js-kit, which TechCrunch bills as “Web 2.0 for lazy people,” more than a year ago. The first time TechCrunch blogged about js-kit’s commenting system, and then the 2nd time, the site blogged about the ratings system.

Js-kit is great because you just paste two lines of code into your blog or website and then kapow, you have a ratings and/or commenting system with 0 money spent on coders.

But all your ratings data is hidden in a sea of javascript that cannot be easily scraped.

Imagine you’re a long-time customer of js-kit. It’s two years later. You need to do some web analytics on the ratings. You’re wondering, “How do I steal all of my data for Js-kit?”

I emailed Js-kit this past Wednesday asking them to how to access my ratings. So far no word from them.

But if you’re like me and have watched The Matrix a few too many times, and sometimes dream that you are Neo, then there’s hope for getting your data. I found an easy way to get your Js-kit data that they won’t share with you.

1) Alter your js-kit ratings code so that it has a dom id.

Js-kit ratings code looks like this:
<div class="js-kit-rating" title="" permalink=""></div><script src="http://js-kit.com/ratings.js"></script>

Change it so that it has a unique id. In this example, I use “js_stuff”:
<div id="js_stuff" class="js-kit-rating" title="" permalink=""></div><script src="http://js-kit.com/ratings.js"></script>

2) If you don’t already have it, add prototype.js to your library of scripts. We’ll need prototype’s Ajax class.

3) Create a javascript function for snagging js-kit’s rating. The gist of this function is to dump the innerhtml of the id, js_stuff, and pass it to a script that parses it and snags the ratings.

4) Create a script used for parsing the ratings and saving it to a file or database.

You can see the js-kit rating snagger in action along with source code.

Categories
How-To TechBiz

Facebook Applications

There’s an interesting article on how to build a viral facebook application at Inside Facebook. Articles that frequently update the newsfeed and minifeed, and make use of the invite feature in the API become viral facebook apps.

For some sample facebook application, check out my source code.

Categories
How-To TechBiz

More MySQL 5.1 Benchmarks: My Code is Faster? And Slower? WTF?

I decided to benchmark the code that builds out the partitioned and non-partitioned tables.
The results are very perplexing.

table-type insert select
non-partitioned 34% 1.02%
code-partitioned 26.98% 96.87%
mysql-partitioned 38.89% 2.03%

Code-partitions are fast on the inserts.

MySQL Partitions are fast on the reads.

This seems to suggest a complicated MySQL master-slave set up where you just have code partitions on the Master and MySQL partitions on the slave. It’s probably not worth the effort setting up, so I’ll just go with the MySQL partitions and work on finding ways to make the MySQL code work faster.

What do you folks think?

Categories
How-To TechBiz

Upgrading to MySQL 5.1: I Love Built-in Table Partitioning!

If you upgrade to MySQL 5.1 (which is still in beta), you will love the performance boost you get over the partitioning that you’re probably doing on the scripting side because of what Yahoo told you. I think improving the “front-end” is great and all, but if you look at the recent benchmarks below run on MySQL 5.1, you’ll see that Yahoo cannot escape the reality of backend speed.

At this week’s Web 2.0 Expo, Yahoo is telling folks to make things work faster on the front end. It’s a great sound-byte, but stupid advice.

If you upgrade to MySQL 5.1 and use its built-in table partitioning, I’m betting that you’ll see a speed boost in selects of up 300%.

Are you ready to Benchmark? I’m assuming that you’ve done a PHP / MySQL install before.

Part I: Installation of MySQL 5.1

  • Download the beta version of MySQL 5.1
  • Back up your mysql database.
  • DO NOT RUN mysql_upgrade. As of this blog posting, it does not work. You wil lock yourself out of your database and go through a painful rebuild process.
  • Install MySQL 5.1 fresh as a new install. If you’re me and want to use partitioning this means: ./configure –prefix=/usr/local/mysql –with-ssl –with-partition ; make ; make install
  • Restore the backed up mysql database.
  • Get your database up and running again.

Part II: Get benchmarking scripts up and running

  • I used PHP 5, and PHP Pear’s Benchmark package.
  • Download the Partition Benchmarks scripts.
  • 3 types of tables are benchmarked: partitioned by software (i.e. Yahoo’s way and how a lot of folks did it before MySQL 5.1), partitioned by MySQL, and not partitioned at all. The script is called build_tables.php . It works on the command line like this: php build_tables.php 10000 5, where 10000 is the number of total rows you’re expecting, and 5 is the number of table partitions.
  • After the tables are built you can now test a select using the testDao.php script by typing: php testDao.php

The results I got on a 1 Ghz PowerPC G4 running Mac OS X 10.4.9 are interesting.

First I built a 5 partitioned tables spanning 10000 rows:
shell> php build_tables.php 10000 5

Then I ran the tests on the 3 partition types: software, mysql, and non-partitioned:
shell> php testDao.php

Elapsed time between Start and Test_Code_Partition: 0.059307
Elapsed time between Test_Code_Partition and DB_Partition: 0.005882
Elapsed time between DB_Partition and No_Partition: 0.003694
------------------------------------------------------------------
marker                time index            ex time         perct   
------------------------------------------------------------------
Start                 1176964205.32067900   -                0.00%
------------------------------------------------------------------
Test_Code_Partition   1176964205.37998600   0.059307        85.83%
------------------------------------------------------------------
DB_Partition          1176964205.38586800   0.005882         8.51%
------------------------------------------------------------------
No_Partition          1176964205.38956200   0.003694         5.35%
------------------------------------------------------------------
Stop                  1176964205.38978100   0.000219         0.32%
------------------------------------------------------------------
total                 -                     0.069102       100.00%
------------------------------------------------------------------

The non-partitioned set up ran the fastest — but that’s no surprise b/c the number of rows aren’t large enough to take advantage of partitioning.

Built-in Partitioning came in 2nd.

PHP partitioning, or software partitioning came a distant 3rd.

So what are you waiting for????

If you need that urgent speed boost in your database-driven web application, get MySQL 5.1 now.

Categories
How-To

taking pics every hour with isightcapture

I just started using isightcapture, a command-line tool for creating pics from your isight on Mac OS X. It’s pretty easy to use.

Save isightcapture to your bin.

Type isightcapture name_of_your_pic.jpg and voila, a pick of you.
You can also crontab it with

5 * * * * isightcapture $HOME/Pictures/icons/crontab.jpg

Categories
How-To

I digg leet Mac OS X command line stuff

Hey, did you know you can put your favorite dashboard widget on your desktop without having to hit F12?

Check out the Top 15 hidden terminal commands for Mac OS X.

It is eeee-l33t.