Browse Author

Andrews Ang

Laravel: “Allowed memory size exhausted” error during unit tests

I’ve been using in-memory testing for my projects based on Laravel every since I found this great  tutorial: http://net.tutsplus.com/tutorials/php/testing-like-a-boss-in-laravel-models/

It was working very well as my test cases increases, to a point when I’m starting to get this error message:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 16 bytes) in /Applications/AMPPS/www/project/vendor/symfony/console/Sym
fony/Component/Console/Command/Command.php on line 57

I couldn’t find the proper solution, but managed to get it working with a workaround here: http://forums.laravel.io/viewtopic.php?id=11723

We can temporarily increase the memory limit using this function:

// Temporarily increase memory limit to 256MB
ini_set('memory_limit','256M');

In my case, I needed more than 128MB of memory, so I conveniently increased it to 256MB. It depends on your usage and your hardware. Choose accordingly.

Since this is only required during my test (I follow the TDD approach, so testing comes regularly), I had added it in the TestCase class, inside method createApplication().

This is the full code in TestCase.php.

<?php

class TestCase extends Illuminate\Foundation\Testing\TestCase {

public function createApplication()
{
    // Temporarily increase memory limit to 256MB
    ini_set('memory_limit','256M');

    $unitTesting = true;
    $testEnvironment = 'testing';

    return require __DIR__.'/../../bootstrap/start.php';
}    

/**
 * Default preparation for each test
 */
public function setUp()
{
    parent::setUp();
    $this->prepareForTests();
}

/**
 * Migrates the database and set the mailer to 'pretend'.
 * This will cause the tests to run quickly.
 */
private function prepareForTests()
{
    Artisan::call('migrate');
    Mail::pretend(true);
} 

}

jQuery using $.on to call newly added elements

More than a year ago, I had written a blog about how to bind events to newly added elements using jQuery.

The scenario can be found here: http://blog.kongnir.com/2012/02/08/jquery-function-not-binding-to-newly-added-dom-elements/

In my previous solution, I had used $.live() in place of $.change(). However, as noted by a commenter in that blog, as of time of writing, $.live() is deprecated.

Instead, we should now use $.on() if you need to capture events of newly added elements.

For example, in normal circumstance, we would do this:

$(".existing-button").click(function() {
    alert("This will work if button already exist on load");
});

However, if you add new elements to the document using AJAX, then the above will not work. That button doesn’t exist.

In both circumstances, this will work:

$(document).on("click",".new-button", function() {
    alert("This will work even if element is newly added");
});

If you notice, the syntax is quite different. The element to call on is the containing element, not the element that the event is called. So let’s say “.new-button” is contained within “#main”, then the following should work too.

$("#main").on("click",".new-button", function() {
    alert("This will work even if element is newly added"); 
});

Reference: http://api.jquery.com/on/

Laravel 4: things to note when creating Package

NOTE: This tutorial was written for Laravel version 4.0. I’ve added some notes for version 4.1 but they’re not tested yet. Do let me know if you see any problem.

When I first started using Laravel 4, I had been creating all my models, controllers and views in the root app folder. While things can get too comfortable and convenient here, it may not be a good idea to dump everything at the top. That’s when Package (or Bundle) comes in.

According to Laravel’s documentation:

“Packages are the primary way of adding functionality to Laravel.”

I found 2 great tutorials on creating your own Laravel 4 Package:

  1. http://culttt.com/2013/06/24/creating-a-laravel-4-package/
  2. http://jasonlewis.me/article/laravel-4-develop-packages-using-the-workbench

The following are some of the problems I’ve encountered and it took me quite some time to look for the solutions. Hope this will help someone else too.

1. Define your dependencies

A Package is like a sandbox module where it should contain its own dependencies (or vendors Packages). So you need to add your dependencies to your Package’s composer.json file.

As an example, I needed to include Cartalyst Sentry and Twitter Bootstrap to my Package, this is what I did under “require”:

"require": {
        "php": ">=5.3.0",
        "illuminate/support": "4.0.x",
        "cartalyst/sentry": "2.0.*",
        "twbs/bootstrap": "3.0.*"
},

 NOTE on Sentry:

After writing this blog, I’ve decided to move Sentry out of my package. Firstly, it will be cleaner and allow people using my package to choose their own authentication vendor. Secondly, I was getting so much trouble trying to get it to work properly. So it’s advisable to just put it on the Laravel app root instead.

Remember to run the following command line at your Package’s root folder:

php composer.phar update
php composer.phar dump-autoload

Note: On your first install, run “php composer.phar install”. Although using update will do the same thing too.

For dump-autoload, on the official documentation, they are using artisan instead of composer. I’m still not sure what’s the difference, but both seem to work.

php artisan dump-autoload

2. Extending Controller

When you download the Laravel 4 master, you will get a BaseController.php under the app\controllers folder. It looks something like this:

<?php

class BaseController extends Controller {

    /**
    * Setup the layout used by the controller.
    *
    * @return void
    */
    protected function setupLayout()
    {
        if ( ! is_null($this->layout))
        {
            $this->layout = View::make($this->layout);
        }
    }
}

And then all your custom controllers will extend this BaseController like this:

class CustomController extends BaseController {}

If you copy and paste this BaseController to your Package, it will not work. The Package will try to find “Controller” in your namespace Vendor\Package.

So to make it work, you must first define BaseController under your namespace, and then let Package knows that it needs to find the correct Controller.

In short, use this:

<?php namespace YourVendor\YourPackage;

use \Illuminate\Routing\Controllers\Controller;

class BaseController extends Controller {

     /**
     * Setup the layout used by the controller.
     *
     * @return void
     */
    protected function setupLayout()
    {
        if ( ! is_null($this->layout))
        {
            $this->layout = View::make($this->layout);
        }
    } 
}

Note for Laravel 4.1:

In Laravel 4.1, the Controller path has been moved. See http://laravel.com/docs/upgrade

Use this instead:

<?php namespace YourVendor\YourPackage;

use \Illuminate\Routing\Controller;

class BaseController extends Controller {

     // Your code
}

3. Using Sentry in your Package

Just to be clear, as some readers mistaken “Sentry” as my Package’s name. It’s a third party Package created by Cartalyst: “Sentry is a simple, powerful and easy to use authorisation and authentication package.” I wanted to include this third party Package in my custom Package to add authorisation and authentication capability.

But once Sentry is downloaded and installed to my Package, I still couldn’t get it to recognise the alias “Sentry”. So the following code produces an error:

Sentry::logout();

The FatalErrorException message was:

Class ‘Vendor\Package\Sentry’ not found

That’s right, the Package has mistakenly treated Sentry under my Package’s namespace.

If you remember from Laravel’s basic documentation, while in the app’s root folder, we can define aliases such as “Sentry” in the \app\config\app.php file. But there doesn’t seem to have any way to register that in my Package.

So what I did, as a workaround, is to include the namespace at the top of my file. Like this:

<?php namespace YourVendor\YourPackage;

use Cartalyst\Sentry\Facades\Laravel\Sentry;

class CustomController extends BaseController {
    public function logOut()
    {
        Sentry::logout();
    }
}

Works like charm! But if you know of a shorter and better way, please leave me a message!

Better solution (edited)

Thanks to hardik dangar, there’s actually a shorter way to do this. Simply add a backslash before Sentry so that php doesn’t search Sentry within my namespace.

<?php namespace YourVendor\YourPackage;

class CustomController extends BaseController {
    public function logOut()
    {
        \Sentry::logout();
    }
}

4. Using Illuminate Facades

Just as you thought everything is well and ready to code, you found yourself stuck at this line!

return View::make('vendorpackage::users/view');

And the FatalErrorException message is:

Class ‘Vendor\Package\View’ not found

What the?!

The same goes to Redirect, Input and Validator.

Base on my previous experience with Sentry, I got just the right idea.

Simply add the following to the top of your code:

<?php namespace YourVendor\YourPackage;

use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\View;

class CustomController extends BaseController {

Tada!!

Better solution (edited)

Thanks to hardik dangar, there’s actually a shorter way to do this. Simply add a backslash before View so that php doesn’t search View within my namespace.

return \View::make('vendorpackage::users/view');

5. Using Views in your Package

That right, you didn’t see it wrongly. This is how you call your Package’s view.

For example, we want view “users\view”, add your Package’s name to the front like this:

View::make('vendorpackage::users/view');

Then how about using master layout? Same logic, like this:

@extends('vendorpackage::layouts.master')

Where the directory is:

workbench\yourvendor\yourpackage\src\views\layouts\master.blade.php

6. Extending Eloquet in your own model

Laravel documentation taught us this:

class User extends Eloquent {}

This won’t work in a Package. Instead, you should do this:

<?php namespace YourVendor\YourPackage;

use Illuminate\Database\Eloquent\Model;

class User extends Model {}

7. Using Controller in your Package

This used to work:

{{ Form::open(array('action' => 'UserController@postStore')) }}

But to use your Package’s Controller, you need to add your Vendor\Package namespace to the Controller like this:

{{ Form::open(array('action' => 'YourVendor\YourPackage\UserController@postStore')) }}

8. Loading Package Config file

If you want to create a separate database for your package, you can define your database configuration within your package directory:

workspace\vendor\packagename\src\config\database.php

Then add this to the package service provider boot() method:

public function boot()
{
    $this->package('vendor/package');
    include __DIR__."/routes.php";

    // Add my database configurations to the default set of configurations                        
    $this->app['config']['database.connections'] = array_merge(
        $this->app['config']['database.connections']
       ,Config::get('package::database.connections')
    );
}

Source: http://stackoverflow.com/questions/15304722/eloquent-laravel-4-package-database-configuration-format

9. Loading external package within Providers and Aliases

In normal circumstances, when we add a new package to a Laravel installation, we would edit the config/app.php by adding the package namespace within the “Providers” and “Aliases” arrays.

However, when we need to add another external package that is a requirement within our own custom package, we wouldn’t want our users to edit a long lists of Providers and Aliases. Ideally, they should only include our custom package.

I’ve been searching for awhile and finally found a solution from this forum.

Solution:

In this example, we want to add an external package call “Markdown”.

In the file myLaravelProject/workbench/my-vendor/my-package/src/MyVendor/MyPackage/MyPackageServiceProvider,

put this in the boot() method:

$this->app->register('SomeExternalPackage\Markdown\MarkdownServiceProvider');

and this in the register() method:

$this->app->booting(function()
{
    $loader = \Illuminate\Foundation\AliasLoader::getInstance();
    $loader->alias('MyPackage', 'MyVendor\MyPackage\Facades\MyPackage');
    $loader->alias('Markdown', 'SomeExternalPackage\Markdown\Facades\Markdown');
});

10. Override config files of package

If you want to be able to allow the users who use your package to publish and modify the package’s config files, following this tutorial:

How to override config files of Laravel 4 package

Tricky WebDev: Fix missing list’s text in Mobile browsers

I had this very strange bug that didn’t show up in Desktop browsers (Chrome and Firefox) but in Mobile browsers, specifically iOS Safari and Chrome.

On Desktop:
tags_on_desktop

On Mobile:
tags_on_mobile

Since I couldn’t find a way to debug on the Mobile browsers, I had spent quite a while trying to figure out what went wrong. It’s also very strange to actually see the texts that have more than 1 word to appear, but yet it only shows the first word.

So I checked the HTML code from Chrome and saw this:

<li>
    "                             Face                             "
</li>

That’s because in my PHP code, I had actually echoed the text on a new line like this:

<li>
    <?php echo $tag; ?>
</li>

Out of curiosity and pure trial-and-error, I had decided to try this:

<li><?php echo $tag; ?></li>

To produce this:

<li>Face</li>

Guess what?
That solved the bloody issue I had been investigating for many hours.
I think I really need to re-learn the basics of HTML.

Missing notes for Laravel 4

Tutorial: Missing notes for Laravel 4

Note: This is an on-going blog. I’ll be updating it whenever I have new findings for Laravel 4.

I had been learning CodeIgniter and CakePHP for some time now when I chanced upon this new(er) framework called Laravel (http://laravel.com) via Twitter.

I’m not going to tell you how wonderful it is, but here’re some references:

There’s an official documentation and another one which is almost recommended everywhere I googled.

The thing is, the official documentation isn’t very complete. It covers most of the basics, but when you want to dig deeper, you’ll get lost. The other recommended tutorial site is almost outdated. I couldn’t find some of the things when I’m comparing it to the official documentation.

So I’m taking notes on the things that I’ve found out (either through googling or the official API documentation). Here we go:

1. Form::open_for_files() is outdated

If you’re trying to create a form for uploading files, the old way was to open the form with Form::open_for_files().

It isn’t clear in the official documentation or the API that we should now use the same Form::open() but now with an additional argument ‘file’ => true.

{{ Form::open(array('action' => 'UploadController@postImage','files'=>true)) }}

2. Using Input::file()

You must always set ‘files’ => true in the Form::open() otherwise Input::file() will never work.

3. Getting filename from Input::file()

There were many tutorials saying that the following will return the filename of the upload file. But it didn’t work for me.

$filename_neverwork_forme = Input::file('image.name');

Instead, use this to get the filename of the upload file.

$filename_worked = Input::file('image')->getClientOriginalName();

Of course, using the filename directly without verification is dangerous. But that’s up to you to decide.

4. Redirect with validation error message and inputs

I realize most methods with underscores are outdated.

So this is wrong:

return Redirect::to('form/create')->with_errors($validation)->with_input();

This is the correct method:

return Redirect::to('form/create')->withErrors($validation)->withInput();

5. Getting URL of a location using URL::to()

To get the full URL of any location or route, simply use URL::to().

For example, if you need the URL of the route ‘about’

{{ URL::to('about') }}

Note: Remember to set your route.php correctly. This function depends on that.

6. Checking current location with Request::is()

I needed to track the current location so that I can mark the corresponding navigation button as active. In this case, you can use Request::is().

Example

@if ( Request::is('about') )
    <li class='active'>
@else
    <li>
@endif
        <a href='{{ URL::to("about") }}'>About</a>
    </li>

 7. Get distinct values from a table column

I had a list of string from a table column that can be repeated. So I needed to query the database to give me an array of string which are distinct.

This is how you can do it:

DB::table('tableName')->select('columnName')->distinct()->get()

 8. Using Mail::send()

This is quite frustrating because the official documentation didn’t describe how to use the $data parameter which is required when using Mail::send().

Found this very good tutorial:

http://maxoffsky.com/code-blog/sending-e-mail-with-laravel-4-using-mail/

 9. Deploying your Laravel project to a shared hosting

Reference: http://stackoverflow.com/questions/16683046/how-to-install-laravel-4-to-a-web-host-subfolder-without-publicly-exposing-app

9.1 Look for your root or home directory

If you’re not sure where is your root or home directory, login to your shared hosting’s cpanel (control panel) and look for the Home Directory. It’s usually something like “/home/domainname”.

9.2 Create a new folder to host the protected Laravel files

We need to create a new folder in the root directory so that they’re not accessible to public. Under the root directory (e.g. /home/domainname/ or example.com), create a folder “applications”.

Under “applications”, create a folder with your project name (e.g. project_name) and place all your Laravel files (except the “public” folder) into this folder.

9.3 Public folder

Put all your files inside Laravel’s public folder into /home/domainname/public_html/project_name.

9.4 Final folder structure

The end result of the folder structure will look like this:

- /home/domainname
    - applications
        - project_name
            - app
            - bootstrap
            - vendor
            - artisan
            - composer.json
            - phpunit.xml
            - server.php
    - public_html
        - project_name

9.5 Edit Laravel’s /bootstrap/paths.php

I was very lost how many “../” I need to add in order to get to the correct path. So we won’t use __DIR__ at all. We’re going to define the full path base on the root directory so that there’s no confusion.

So change from this:

return array(
    'app'     => __DIR__.'/../app', 
    'public'  => __DIR__.'/../public',
    'base'    => __DIR__.'/..',
    'storage' => __DIR__.'/../app/storage',
);

To this:

return array(
    'app'     => '/home/domainname/applications/project_name/app', 
    'public'  => '/home/domainname/public_html/project_name',
    'base'    => '/home/domainname/applications/project_name',
    'storage' => '/home/domainname/applications/project_name/app/storage',
);

9.6 Edit Laravel’s /public/index.php

Same as the point above, we’re not going to use __DIR__. Let’s change all the path to full path.

From this:

require __DIR__.'/../bootstrap/autoload.php';
$app = require_once __DIR__.'/../bootstrap/start.php';

To this:

require '/home/domainname/applications/project_name/bootstrap/autoload.php'; 
$app = require_once '/home/domainname/applications/project_name/bootstrap/start.php';

9.7 Edit .htaccess

If your shared hosting’s default PHP version is < 5.3.7 but they support higher versions, you can edit the .htaccess file inside the “public” folder.

For Mac users, you can access it via the Terminal.

Use this command to go to the folder

cd your/laravel/path/public

Then list hidden files with this command

ls -a

You should see .htaccess there. By default, this file is protected. In order to change it, you need to open it using super user like this:

sudo open -e .htaccess

Note: -e means open with text editor.

Then append this line to the bottom and save it.

AddHandler application/x-httpd-php53 .php

Or if you want version 5.4

AddHandler application/x-httpd-php54 .php

Upload the updated .htaccess to the public_html/project_name folder and you’re done!

10. Returning view with Error message

When you need to return to a page with error messages (especially if you use validation), you can pass the error messages back to a view with this:

return Redirect::to('form')->withErrors($validation)->withInput();

However, if you need to return an error that is not captured in Laravel’s validation, for example, I needed to check if the reCAPTCHA returns a matching input, you can create a new MessageBag and return that error messages instead.

$errors = new IlluminateSupportMessageBag;
$errors->add('customError', "The reCAPTCHA wasn't entered correctly.");
return Redirect::to('form')->withErrors($errors)->withInput();

But what if you have both validation and custom message? This is how I’ll do it: first, check that validation has passed, if not, return with validation error messages. Then, check that, in my case, reCAPTCHA is matching, if not return that error message.

Example:

if( !$validation->passes() )
{
    return Redirect::to('form')->withErrors($validation)->withInput();
}

// CAPTCHA was entered incorrectly
if (!$reCaptcha->is_valid) {
    $errors = new IlluminateSupportMessageBag;
    $errors->add('reCaptcha', "The reCAPTCHA wasn't entered correctly.");
    return Redirect::to('form')->withErrors($errors)->withInput();
}

11.Creating a Package

Reference:

Important commands:

  1. To generate the class map of package:
    composer dump-autoload
  2. To move package’s assets into public/packages:
    php artisan asset:publish --bench="vendor/package"

12. Laravel requires Mcrypt PHP extension

If you’re using Mac like me, the default PHP installed on the Mac doesn’t insclude Mcrypt extension. I’m using MAMP for development and testing, so I followed this method and it worked for me.

Reference: http://stackoverflow.com/questions/16830405/laravel-requires-the-mcrypt-php-extension

Enter “which php” in terminal to see which PHP you are using.

which php

By default, Mac uses PHP from this path:

/usr/bin/php

If it’s not the PHP version from MAMP, you should edit or add .bash_profile under user root document (cd ~).

In .bash_profile, add following line (your MAMP version may be different, so does your PHP version. Check it up on the folder /Applications/MAMP/bin/php/):

export PATH=/Applications/MAMP/bin/php/php5.4.4/bin:$PATH

And restart Terminal to see which PHP you are using now. And it’ll be working by now.

13. Using lists for Form::select()

The shorter way to populate an array to be used in Form::select() is using query builder ‘lists’ to retrieve just the id column and a value column.

For example:

$select_array = Classname::lists('name', 'id');

Read the link below for more tips about this trick.

Laravel 4: Using query builder lists for Form::select

Prepaid SIM card in Switzerland and Germany

Travel Tip to Switzerland and Germany

Just came back from Zurich-Munich trip. I’ve the habit of reading online news (via Flipboard) and playing mobile games that require internet connection during travel. Especially if I need to travel a lot locally from places to places. So whenever I visit a country, I’ll always look for their prepaid SIM card with data connection options.

For Switzerland, it seems like an easy option, because Swisscom is everywhere, somewhat like our Singtel in Singapore. I had signed up for their NATEL easy smart prepaid SIM card. It costs CHF19.90, including CHF20 credit. They charge CHF2 per day for unlimited data access. This is the default option so no need to activate data plan. Essentially the card can last up to 10 days of unlimited data access. My friend and I used Whatsapp to communicate so we didn’t need to call each other at all. Like I’d said, Swisscom is everywhere. You can find their store in Zurich airport and the central train station. The staffs were friendly but it took them about 30 to 45 mins to help you register your card, allow some time for this before you plan anything else. Passport or identity card is required for registration. The connection was generally good, even in areas such as Lauterbrunnen and Jungfraujoch. By the way, most stores in Zurich open at 8am, so if you arrive early, you may need to wait till then. They provide nano SIM card, so remember to ask for it if you’re using iPhone 5. The settings are done automatically when you insert the card.

As for Germany, it took me quite a while to understand the “big” and “small” providers. If you read up the internet, you’ll see a long list of mobile plan providers in Germany. In short, the smaller providers tag on to the bigger providers’ network and provide services to their own customers.

After a long search, I found in a forum this Blau.de which offers a cheaper option and it’s available in an electronic shop in the Munich airport. It tags on to the E-plus network. Unfortunately, they don’t have an English website, but fortunately we have Google Chrome to help do the translation. So I got this Blau.de 9-cent Tarif plan for Germany. You can get it from Munich airport Electronic store or any E-Plus stores. It costs 20 Euro (includes 10 Euro credit). You can ask the staff to help activate the 9.90 Euro plan for 1GB data for 1 month (the staff in the Electronic store told me it’s actually unlimited, but first 1GB at high speed). It will use up all the credits you have but again, my friend and I used Whatsapp to communicate so we didn’t need any credit for phone calls. If you need nano SIM card, the staff at the Munich airport electronic shop will help to cut it for you. Make sure you ask the staff to set up the data internet settings, it can be quite complicated. And to be very sure, remember to update and backup your iPhone before you travel. There was this girl with iPhone 4 or 4S at the counter when I was there. She couldn’t connect to the internet because she was using a very old version of iOS, which didn’t support Germany network. The overall data connection was generally good but patchy at some places. I had experienced good and poor connection just within 2 streets. But the network was fine in most popular attractions.

I hope this is useful for people who are planning to travel to Switzerland or Germany.

To the teachers who inspired me

I was a quiet boy in school when I was little. I never had any close friends before secondary school because I had very low self-esteem.

I think my self-confidence was more or less damaged by the comments I got from my relatives and friends. My dad was in debt, my mum was an alcohol sales girl, my sisters were dropped out from school, I never did well in school and I was a sissy. Yes, I got a lot of that “sissy” comments. It got so deep into me that I was troubled by it for the longest time in my youth.

I tried to stay away from the boys in primary school because they would make fun of me. I always thought being sissy was a wrong thing, so I didn’t want the other boys to hear me talking. I pretended to be like them: talking loudly, mocking at others, cheating during tests, playing truant and pulling girls’ pony tails. But to me, they were not my friends. The girls hated me too.

Actually, playing truant wasn’t exactly just for show. I didn’t like school, didn’t like the teachers and classmates. It didn’t make any sense to go there at all. Although, I loved drawing. I scored well in my art and craft. My art teacher even praised me during meet-the-parent session. But my dad would say drawing was for girls. So I dropped it.

My elder sister was very good in sports. She was one of the top badminton players in school and she always participated in track and fields. I admired her a lot, still do. I took part in drama and I drew very well, but I was never good in sports. My dad and relatives would laugh at me for doing the “girls stuff”. I tried soccer. It was a disaster… I could only chase the ball and mocked by the other boys.

I ever thought I had made a good friend when I was in primary 4. He would ask me to go over to his house and we would make our own toy cars. I thought finally I was doing what other boys would do. And then one day my good friend offered to help me make my toy car look better. The model I bought was one of the most expensive ones available at that time. I had saved up all my breakfast money to buy it. So naturally I was very particular about all the parts in my toy car. The next day my good friend played truant. The following day he didn’t show up. So I went to his house to ask if I could get my toy car back. He gave me back, reluctantly. I was beginning to feel suspicious. So I checked every part of my toy car… The engine was different… I remembered I made a mark on it. So I questioned him, and of course he denied and blamed me for being so sissy. What?!

Then, I never trusted anyone. And I stopped talking. I had even stopped going to school. Every morning, I would dress up nicely, pretending to go to school. Then I would wait on the upper floor for my dad to leave for work. I would go back to my house and hid under the bed or in the cupboard for the next couple of hours. I hated school. In fact, I hated people.

There was this social studies teacher who was always concerned about my attendance. If I didn’t turn up in class, she would talk to me the next day when she saw me. I was so petrified whenever she called me out in class, and then questioned me about my medical certificate. Many years later, I read in a news that she had won some awards for the most caring teachers in Singapore. Now that I think of it, she really deserves that award. Her name was (something like) Ms Synnathambhi. I can’t spell her name now. 😛

I failed primary 5, really badly. During that time, for students who failed primary 5 or 6, they would either go to extended classes or mono classes. Primary school would usually end at primary 6. So the extended classes would continue to primary 7 and 8. While the mono classes would continue to primary 7 and 8, but they could never go to the main stream in secondary school.

I ended up in an extended class, jumping from primary 5 to primary 7 extended.

As usual, in the first few weeks, I always turned up late. Then one day, my maths teacher, Ms Gwee, saw me coming into the class, late, and said in front of the class: “Oh wow, you’re early!”

I was terribly embarrassed like never before. But she didn’t continue to humiliate me in front of the class. She waited for me to settle down and then continue with her lesson. This was the most important lesson in my life! The first sarcastic remark I had gotten. Yet, it helped me to realize how selfish I was to let the others wait for me to begin class. She didn’t look at me like other teachers. What I saw from her was the same look she gave to every other student in the class. That was the first time I felt at ease in class. I didn’t have to behave like others, because I was “others”. From that day onwards, Mathematics became my favourite subject. I had even scored an A star in PSLE, our national Primary School Leaving Examination, almost on par with the normal stream primary 6 students. I’m sure Ms Gwee was very proud of me.

During the same time, I had also met another important teacher in my life. She was my Chinese language teacher. I must admit, I forgot her last name. But I remembered I was very bad in Mandarin. At home, my parents and relatives would communicate in Hokkien (Min Nan), a dialect passed down from my grandparents who were from the south China. English and Mandarin were foreign to me at that time. I had even written my assignment in Hokkien without knowing. She read it out in class (in Hokkien) to humiliate me. It was so embarrassing, yet funny because she did the Hokkien slang the right way! But the most important thing was, she pointed out to me what was wrong, and corrected me. I felt so blessed. And comforted. Because she understood my background. She didn’t blame me, but praised me for what she could never do! Yes, you guessed it. Mandarin became my next favourite subject and I got A in PSLE.

I then became “teachers’ pet”, and was hated by many classmates. I didn’t want that. I only wanted to be kind to people who treated me kindly. Unfortunately, those people were my teachers.

While I was quiet in school during my time in primary 7 and 8, there was this guy who was in my class and had been mocked by many students as a sissy. He was always alone and quiet. During recess time, you would see him hiding in a corner, eating his breakfast. One day, during physical exercise lesson, under the impression that all the other boys didn’t like him, I mocked at him loudly across the parade square, shouting “sissy”. He merely looked away, hurt. And then a boy whom I admired for a long time, spoke out for him and scolded me for being rude. It shocked me… because I always thought people didn’t like sissy. And then I realised that I was wrong to judge people. I was in no position to judge people, especially when I was in the same position… a “sissy”. That “sissy” became my first good friend in school.

I didn’t do well in English, but squeezed my way through the express course in secondary school, it was the same couse that the normal primary 6 students would go. My teachers were thrilled, but my dad didn’t know the difference. He only wanted to know if I had “passed”. I just told him I did. My mum, on the other hand, knew that I was “first in class”, and insisted that we celebrate at the coffee shop she worked in. She began telling her colleagues how smart I was. You can imagine how embarrassed I was at that time. I was just an “extended student”, which was deemed as no future at that time.

In my first year in secondary school, I had tried to keep away from other students. I hardly spoke to anyone, even my good friend from primary school. During recess time, I would buy my breakfast and do my homework in a corner. It felt safe…. because I didn’t have to face human beings. Until we were forced to join an ECA (Extra Curriculum Activity).

I loved arts and music. So the first ECA that I thought would be either the band or the choir. But then I was pressured by my relatives to do something more “manly”, which I thought could be the boys scout or NPCC.

My form teacher, Ms Chang, was the teacher-in-charge of the band. We were the pioneer batch of the school, so all ECAs were only just starting. Eventually, I had decided to give the band a try, thinking that I could learn the violin. Ms Chang very kindly explained to me that the band wasn’t an orchestra, so there wasn’t any violin available. I was quite disappointed at that time. She then encouraged me to try other instruments later on in that year (it was a new school, so there wasn’t any instrument to practice for many months). I don’t know what came to me, but I stayed in the band eventually. Trombone was my first musical instrument.

I knew Ms Chang took care of me. I didn’t know why. But in my second semester of the first year, she made me the chairman of the class, and then she made me stand in front of the class to make announcements. Initially, I was very shy and afraid… but after a few rounds, I gained some confidence and spoke better with people. Later on, she even made me the drum major of the band. I knew she was trying to help me regain my self-esteem, but I had also heard rumours about people not happy with my position. It was difficult to deal with rumours at that young age. The discipline master even tried to make me the Head Prefect, but I rejected… because I couldn’t deal with so much pressure at the same time.

We did well in our band competition, although not ideal, but I had enjoyed every day with the band members. It was then that I felt ease and comfort with people of the same mindset and without prejudice. Yes, we were only maybe 12 to 16 years old. But the amount of pressure from our peers was no lesser than the adults.

Along the years, I had met many other great teachers who had guided me to a clearer path. I may not be successful now. But I’m more human, more self-esteem, and more open to people who care about me. To those teachers who had changed my life, if not for you, I won’t be writing this blog in front of a 27 inch iMac comfortably, and I won’t be having so many good friends in my life. Thank you so much! Oh, and I may still be a sissy, but I have come to accept it as part of my life! 🙂

Fix file association error in Windows 7

I’m having this very strange Perl scripts association issue in Windows 7 that is causing my automation to fail with strange warnings. Perl script launches correctly but doesn’t detect any parameters passed into it.

To fix this, I had to remove some keys in RegEdit.exe to reset the association.

Go to “Start button” -> search for -> “regedit”, and delete the following:
HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerFileExts.pl
HKEY_CLASSES_ROOT.pl
HKEY_CLASSES_ROOTpl_auto_file

Hope this helps people with the same problem.

References to good BYO PHP MVC Framework tutorials

When I first came across the term MVC (Model-View-Controller) few years back, the whole concept sounded so complex, especially for people with (old) ASP and PHP background. In those days, we were so used to mixing business logics inside the presentation layer. It was so logical and convenient, until the code got big and things got out of hand. We forgot where the codes were, and we risked stability even for small changes to the UI, because they were all intertwined with business logics.

Typical PHP-HTML mixed code:

<?php
  include "someFileContainsFunction.php";
  public function someLocalFunction( $param )
  {
    return "Business logic in <b>$param</b>!";
  }
?>
<html> 
  <title>HTML with PHP</title>
  <body>
    <h1>My Example</h1>
    <?php
      print someLocalFunction( "Inside body" );
    ?>
    <b>Here is some more HTML</b>
    <?php
      print functionFromExternalPHP();
    ?>
  </body>
 </html>

Then I was introduced to MVC during a Microsoft .NET bootcamp in Singapore. I was quite fascinated with the idea. Separating the 3 components enable us to distribute the work to programmers and designers, allowable them to do their work without touching the fields they’re not familiar with. It is also an ideal solution to multinational collaboration.

Although the .NET MVC framework was great as a development tool, I couldn’t understand the fundamentals of building an MVC. We merely followed the coding style requirements by the framework, and work our way through to make the application work.

So I went in search of other languages, and found many other frameworks such as Ruby on Rails (for Ruby) and CakePHP (for PHP). They are also great MVC frameworks, but then again, they’re very established with quite stringent coding style requirements that I always got lost halfway down the development.

http://www.netmagazine.com/features/choose-right-php-framework

I thought the best way to learn about something is to start from the beginning, and keep on testing and failing until I understand it. The following 2 tutorials are great starting points. I managed to write my own MVC framework within a day (or maybe a few hours) by following the tutorial from Domagoj Salopek. I would recommend going through this tutorial first before going to the next one, which is slightly more complex but covers a little more for MVC.

http://www.domagojsalopek.com/Details/Create-a-simple-PHP-MVC-Framework/28

http://johnsquibb.com/tutorials

Of course, there’re people who think that using MVC on a small project is an overkill. Trust me, it’ll help you in the long run. By writing a core MVC framework, you’ll be able to use it in all other projects in the future, regardless how big or small it is. Unless the client only wanted a “simple” website. I know clients always think their requirements are simple because they don’t understand the simpler it seems, the more work it takes. I’m referring to those instances where the project can be done just with HTML and JavaScript. In those cases, MVC is really too much.

Now, going back to fiddling the simple MVC framework that I have written.

Edited: After writing my own simple MVC framework, I went on to study other major PHP framework such as Symfony, CakePHP and CodeIgniter. I noticed that CodeIgniter uses a very similar approach to the simple framework introduced by Domagoj. So if you’re advancing to a more complex framework, take a look at CodeIgniter. You’ll be glad he had written something so fundamental to get us started.

MD5 Hashing password or text using Perl

Just a small tip I learned from work.

Obtain the MD5 hash of the password using Perl:

$ perl -MDigest::MD5=md5_hex -e"print uc(md5_hex(@ARGV[0]))" hellother3

Result:

BB4505B8BC6051AF4A6FEB31A2ECE1E7

The uc() means returning the upper case of the result.

print uc(md5_hex(@ARGV[0]))

To return the lower case of the result, use lc() instead:

print lc(md5_hex(@ARGV[0]))