Categories
php WebApps

sfValidatorCompare Is Now sfValidatorSchemaCompare

I’ve been running into other folks that have been having trouble with symfony 1.1 on Twitter. One common stumbling block is sfValidatorSchemaCompare.

I’m just gonna paste code here, because I’m now a week behind schedule working with symfony 1.1 because I didn’t pad time for having to read a good chunk of the source of symfony 1.1:

<?php

    $this->validatorSchema->setPostValidator(new sfValidatorAnd(array(
	  new sfValidatorSchemaCompare('email', '==', 'email_confirm',
		    array(),
		    array('invalid' => 'The email adresses must match')
		  ),
	  new sfValidatorSchemaCompare('password', '==', 'password_confirm',
		    array(),
		    array('invalid' => 'The passwords must match')
		  ),
	    )));

?>

Anyway it’s been cool getting props for posting code like the above. 😀

Good luck!

Categories
php TechBiz WebApps

Does Core Developer Think Symfony 1.1 Alienates PHP Developers?

Have you ever coded in a framework and then woke up one day to find that all your code broke when you upgraded? That’s exactly what happened when symfony 1.1 was released without backwards compatibility. A core symfony developer, François Zaninotto, shares his thoughts about the non-launch of symfony 1.1.

A couple key phrases, that he uses to describe the symfony core developers attitude to us mortals, are pretty disturbing:

  • If you just used symfony for one project, and left if afterwards because it lacked some feature that you needed, then you don’t deserve to be informed that this new release does have this feature.
  • Symfony 1.1 is so good, that it should not be left in everybody’s hands. Think of it as a forbidden manuscript of the middle ages, that only a few copyists ever read and got a fair picture of.
  • …there is no “First Project tutorial” at all for symfony 1.1.

Caveat: Do not use symfony 1.1 unless you want to pour through source code.

Problem: You’re working on symfony 1.1 and it doesn’t work as advertised.

Solution: You have to pad your estimates on symfony based projects by at least a hundredfold. A form that should have taken me no more than an hour at Dogster ended up taking 4 days! Read this blog for important symfony 1.1 updates.

So does François think that PHP developers are being alienated? It’s strongly suggested through his use of irony, and analogy of symfony to a medieval text, but does he say abandon symfony?

Not at all. Rather his frustration noted in a follow up blog post has to do with the fact that he cares a great deal about symfony. If you were thinking about leaving symfony, François is enough reason to stay.

Categories
How-To php WebApps

Symfony 1.1 Validation — Gotchas

1. sfValidatorAnd requires a patch to work with Propel.

Get the patch here.

Read the trac ticket for more details.

2. A huge difference between 1.0 and 1.1 in form validation deals with error handling.

1.0 puts the error handling right in the action. In 1.1 you use code in a lib/forms file that looks like this for validation / error handling and corresponds usually to the object being validated. In the example below the code is in lib/forms/AccountForm.class.php

$this->setValidators(array(
    'username' => new sfValidatorString(array('max_length' => 30))
));

3. sfForm::setDefaults doesn’t work quite right with CSRF values.
you’ll need to patch up code based on this google groups post.

The documentation right now for 1.1 isn’t updated. E.G. The chapter on forms for the 1.1 documentation as of 12 August 2008 will lead you down the wrong path.

To keep up to date on what’s going on with symfony, I totally consider doing the following mandatory and not optional:

  • Join the google group, symfony-users
  • Join the irc channel in irc.freenode.net #symfony any time you’ve got a question that needs asking
  • Since the docs might be off, it’s best to just read the source.
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
TechBiz WebApps

Algorithms in PHP

I started coding algorithms in PHP in order to beef up my coding knowledge. It’s been an interesting exercise so far because when I coded algorithms in college it was great using C pointers.

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
TechBiz WebApps

Strawpoll, Twitter as a Coral Reef, and Bruce Lee

Dave Winer called Twitter a coral reef last April. It’s the highest compliment he said that he could pay.

When I see something like StrawPoll, that brings together polling and twitter, I think we have to say that Twitter is more basic than a coral reef. Twitter is like water. Without it, you can’t really use the Internet anymore. Google’s search is water, too, and it wouldn’t make sense to have the Internet without it.

StrawPoll also has a beautifully designed front page that reminds me of CSS Zen Garden, a great site for getting inspired about web design.

If you’re making a web app you might want to follow the advice of this guy:

Your web app needs to be like water. Everybody needs water.