Updates from September, 2011 Toggle Comment Threads | Keyboard Shortcuts

  • danielsaidi 9:34 pm on September 15, 2011 Permalink | Reply
    Tags: pear, phpunit, ,   

    Getting PEAR and PHPUnit to work with MAMP 

    When I recently decided to start re-developing a PHP project of mine from scratch, I decided to replace SimpleTest with PHPUnit and PHPCover.

    To get familiar with PEAR, I found this great tutorial:


    However, since I managed to screw up my PEAR configurations when playing around with it a month ago, the tutorial did not work.

    Turns out that PEAR was missing from where I wanted it to be installed, and that multiple PEAR installations were scattered all over the file system. The config file pointed to one of these locations, which made the installer believe that I had the latest release installed.

    Turns out that:

    Finally, I could follow the tutorial at the top of this post. Installing PHPUnit was a breeze after the invalid PEAR settings were fixed.

    You also need to grab PHPCover, which is described at https://github.com/sebastianbergmann/phpunit/

    Now, you have to set the include paths in /etc/php.ini. Mine looks like this:

    • include_path=”.:/php/includes:/usr/lib/php:/usr/lib/php/pear

    However, since I use MAMP, this is not the file that is to be. You need to modify the ini file in MAMP’s configuration area, and add the paths there as well.

    Now, PHPUnit will work, but I am yet to be convinced. SimpleTest seems easier to setup and flexible enough to cover all test cases I need, including mocking…plus that I can ship the testing framework with the development bundle.

    Any thoughts regarding this?

  • danielsaidi 9:05 am on February 2, 2011 Permalink | Reply
    Tags: flash, gears, , , , , plupload, silverlight,   

    Trying out Plupload 

    In Wigbi, I had a really handy UI plugin called FileUploadForm that could upload any number of files with AJAX. All you needed to do was to add such a form to the page to have it handle the entire file upload process automatically.

    However, as I yesterday sat down to migrate the old plugin so that it would work with the new Wigbi version, I thought “hey, three years have passed – there MUST be an even easier way to upload files”. Believe it or not, there was.

    The people behind Tiny MCE have created a really nice file upload component called Plupload. It supports several ”runtimes” – from jQuery-based file upload in HTML4/5 to Flash, Silverlight, Gears etc. and is insanely easy to configure.

    You can tell Plupload which runtimes you’d prefer to use, which file types to support etc. The users can then upload files either with a regular “select file(s)” dialog or by dragging files from an Explorer/Finder window.

    To make Plupload work with Wigbi, I moved the upload.php file to ~/wigbi/pages/ and added some extra functionality, like starting/stopping Wigbi and being able to adjust the target folder with a query string variable.

    All in all, adding Plupload to my Wigbi-based site took 10 minutes and worked perfect.

  • danielsaidi 1:12 am on November 24, 2010 Permalink | Reply
    Tags: magic quotes   

    The horrible magic quotes in PHP 

    A little more than a year ago, I had some problems when AJAX:ing data to a PHP page. In order to be able to unpack the data, I had to use the stripslashes method, which did not seem all that intuitive. However, since it worked, I let it remain without any further considerations.

    Then, about a month ago, I published a new web site that I had developed for a friend. For that page, when I posted HTML content via AJAX, all line feeds turned into u000a strings. The problem only occured on his domain, and not on mine, and looks like this:

    Magic quotes in action - all line breaks are turned into u000a

    Magic quotes in action – all line breaks are turned into u000a

    So then, yesterday, the problem finally appeared at my domain as well. I did not understand this at all, until I chatted with a friend of mine, who just brainstormed and came up with the solution.

    Magic quotes.

    Ok, the purpose of this feature was to protect pages from injections, but it did not work all that well, so the feature is now deprecated. What it does is that is wraps everything in neat little escape slashes, which is why I had to use stripslashes.

    However, if magic quotes are disabled, stripping the slashes will instead destroy the escaped line break.

    So, I now disable magic quotes for all pages, using this in an .htaccess file:

       php_flag magic_quotes_gpc off

    Thanks Mattias – it works like a charm!

  • danielsaidi 10:49 pm on October 5, 2010 Permalink | Reply
    Tags: ,   

    A really simple PHP Controller class 

    I have written a reaaaally simple Controller class to my hobby project, Wigbi. Even though it is SO basic, it will help immensely when developing MVC-based PHP web applications.

    The class has three properties – name(…), action(…) and viewData(…) – and one single method – addView(…). I will try it out in a couple of projects and see if it is good enough.

    Here is the code:

    class Controller
     * @ignore
     private static $_currentViewData;
     private static $_action = "";
     private static $_name = "";
     private static $_viewData = array();
      * Get/set the name of the current action.
      * @access    public
      * @param    string    $value    Optional set value.
      * @return   string              The name of the current action.
     public function action($value = "")
        if(func_num_args() != 0)
           Controller::$_action = func_get_arg(0);
        if (Controller::$_action)
           return Controller::$_action;
        if (!array_key_exists("action", $_GET))
           return "";
        return $_GET["action"];
      * Get/set the name of the controller.
      * @access    public
      * @param     string    $value    Optional set value.
      * @return    string              The name of the controller.
     public function name($value = "")
        if(func_num_args() != 0)
           Controller::$_name = func_get_arg(0);
        if (Controller::$_name)
           return Controller::$_name;
        if (!array_key_exists("controller", $_GET))
           return "";
        return $_GET["controller"];
      * Get/set view data.
      * @access    public
      * @param        string    $key        Optional key value, otherwise current, view specific data.
      * @param        string    $value    Optional set value.
      * @return    string                     The view data value.
     public function viewData($key = "", $value = "")
        if (func_num_args() == 0)
           return Controller::$_currentViewData;
        if (func_num_args() == 2)
           Controller::$_viewData[$key] = $value;
        return array_key_exists($key, Controller::$_viewData)
           ? Controller::$_viewData[$key]
           : null;
      * Add a view to the page.
      * If ~/ is used in the view path, Wigbi will auto-parse it to the
      * application root path.
      * @access    public
      * @static
      * @param    string    $viewPath    The path to the view file.
      * @param    string    $viewData    Optional view data; default null.
     public static function addView($viewPath, $viewData = null)
        Controller::$_currentViewData = $viewData;
        $viewPath = str_replace("~/", Wigbi::serverRoot(), $viewPath);
        require $viewPath;
        Controller::$_currentViewData = null;

    In the application root, I place an .htaccess file with the following content:

    Options -Indexes
    Options +FollowSymLinks
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([a-zA-Z0-9_\-]+)/?$                   controllers/$1Controller.php?controller=$1                        [NC]
    RewriteRule ^([a-zA-Z0-9_\-]+)/([a-zA-Z0-9_\-]+)$   controllers/$1Controller.php?controller=$1&action=$2    [NC]
  • danielsaidi 12:30 am on August 19, 2010 Permalink | Reply
    Tags: , bundle,   

    Bundle JavaScript and CSS files with full file paths 

    I have been looking at the great PHP CSS/JavaScript bundling approach that is presented at rakaz.nl. The suggested approach is great…and works great, but has a small drawback.

    The downloaded combine.php must be adjusted and all combined files must exist in the same folder.

    Not a big problem, I know, but since I have a structure where css/js files may exist in sub folders, I want to be able to provide the bundle URL with full paths to the files I want to bundle.

    Since the original solution is so slick, this is quite easy to achieve. I will not upload my solution for download, since I want you to grab the original code from rakaz.nl so that it receives the visitors it deserves 🙂

    Well, let’s get started:

    • In your project root, create a folder called bundle (or whatever you want, it is not that important)
    • In the bundle folder, create an .htaccess file and add the following code:
              RewriteEngine On
              RewriteBase /
              RewriteRule ^css/(.*\.css) /combine.php?type=css&files=$1
              RewriteRule ^javascript/(.*\.js) /combine.php?type=javascript&files=$1
    • In the bundle folder, create a combine.php file and add this content to it.

    Well, now you’re practically where the original approach tells you to adjust the PHP code a bit. Instead, do this:

    In the combine.php file, replace

              $path = realpath($base . '/' . $element);


              $path = "../" . $element

    The code has to be replaced at two places in the PHP file.

    That’s it!

    The only thing you have to consider now is to use application root relative paths when calling the bundle URL. This will cause your bundle URL to become quiiiite complex, but it works 🙂

    For instance, I have my main JavaScript folder in the application root folder content/js. Let’s say that I have the files a.js and b.js (great naming convention, ey?). The bundle URL would then be:


    To bundle CSS files, the corresponding code would look like:


    Well, you get the point 🙂

    The newly added code will add a ../ to each link before attempting to parse the file, which will work great since the combine.php file is placed one level down from the application root…to which the links have to be relative, remember?

    The great thing now is that I can bundle any JavaScript/CSS files (they still have to be bundled separately) regardless of their physical location (as long as they exist anywhere within the application root folder).

    Another great thing is that the .htaccess file is placed inside the bundle folder, which means that you can just copy the bundle folder if you want to use it in another project.

    Hope this helps!

  • danielsaidi 8:48 pm on August 12, 2010 Permalink | Reply
    Tags: , get_class, ini file, is_string   

    Getting familiar with PHP 5.3.2 

    Since I am no real PHP developer (just pretending), I have just started to use PHP 5.3.2., although PHP 5.3.3. was released a while back. The reason for this is that I’ve just installed Aptana Studio 2, which comes with 5.3.2.

    After installing Aptana Studio 2, I tried to execute a build/packagetest operation for my latest Wigbi version. It did not work, due to two small modifications in PHP 5.3.2.

    First of all, get_class does not accept string parameters anymore, so I’ll just have to change all the places where I use it. Thank GOD for TDD and all unit tests!

    I have used get_class in functions where a parameter could either be a string or an object. Instead, I now use is_string, which actually is a lot cleaner and…better.

    I’ve also noticed that the parse_ini_file function is a bit shaky. It is no longer able to parse ini files that end with a row at which a parameter is specified (like all my previous ini files). The file cannot be parsed, probably since the line feed is considered to be a part of the parameter value.

    I solve this by just adding an extra line after the last parameter. It’s a bit annoying, but I guess that the change is meant to make the function follow some kind of standard, so those extra lines are fine, I guess.

    After adjusting my code to these changes, everything ran smoothly once again.

  • danielsaidi 12:19 am on June 9, 2010 Permalink | Reply
    Tags: , , , virtual file   

    Bundle CSS files with relative file paths 

    I am currently working with bundling CSS files, and have to be able to bundle files from many different folders, when needed.

    Previously, all CSS files within the selected CSS folder (if any), as well as within a mandatory system css folder, were added to the virtual bundle file. The theme engine parsed all files and added them to the virtual file output as one mega string:

       .validation-error{border: solid 1px #bb4444;background: #ffdddd;}.RatingBar .images a{display: inline-block; width: 20px;height: 20px;}.RatingBar .unrated { background-image: url(../../../wigbi/content/img/controls/RatingBar/rating_unrated.gif); }.RatingBar .rated { background-image: url(../../../wigbi/content/img/controls/RatingBar/rating_rated.gif); }.RatingBar .half { background-image: url(../../../wigbi/content/img/controls/RatingBar/rating_half.gif); }.RatingBar .createdBy { background-image: url(../../../wigbi/content/img/controls/RatingBar/rating_createdBy.gif); }.RatingBar .hover { background-image: url(../../../wigbi/content/img/controls/RatingBar/rating_createdBy.gif); }@import url(../../../box.css);@import url(../../../classes.css);@import url(../../../controls.css);@import url(../../../design.css);@import url(../../../elements.css);@import url(../../../grid.css);@import url(../../../lists.css);html, body{margin: 0px;background-color: #FFFFFF;background-image: none;}.box{border: solid 1px #bbbbbb;}.box .body{padding: 5px;border: solid 2px white;background: #f6f6f6;}.w100 { width: 100%; }.w95 { width: 95%; }.w90 { width: 90%; }.w85 { width: 85%; }.w80 { width: 80%; }.w75 { width: 75%; }.w70 { width: 70%; }.w65 { width: 65%; }.w60 { width: 60%; }.w55 { width: 55%; }.w50 { width: 50%; }.w45 { width: 45%; }.w40 { width: 40%; }.w35 { width: 35%; }.w30 { width: 30%; }.w25 { width: 25%; }.w20 { width: 20%; }.w15 { width: 15%; }.w10 { width: 10%; }.w5 { width: 5%; }.align-center { text-align: center; }.align-left { text-align: left; }.align-right { text-align: right; }.valign-middle { vertical-align: middle; }.valign-top { vertical-align: top; }.float-left { float: left; }.float-right { float: right; }.bold { font-weight: bold; }.bold-italic { font-weight: bold; font-style: italic; }.italic { font-style: italic; }.invisible { display: none; }.clear { clear: both; }span.large { font-size: 1.3em; }span.yellow { color: #ff9900; }img.border{padding: 3px;border: solid 1px #cccccc;}#main-content-middle img.top{padding-bottom: 15px;}div.separator{margin-top: 10px;margin-bottom: 10px; font-size: 1px;height: 5px;border-bottom: solid 1px #dddddd;background-image: url(../../../img/themes/pro/bg_lines.gif);}#main-content-right div.section-title{height: 25px;padding: 3px;background: #f6f6f6;border-top: solid 1px #cccccc;border-bottom: solid 1px #cccccc;}#main-content-right img.section-icon{float: left;margin-right: 8px;}#main-content-right div.section-text{font-weight: bold;margin-top: 7px;margin-bottom: 15px;}.control input[type="text"],.control input[type="password"]{width: 98%;}.control textarea{width: 99%;}.control-body div{margin-bottom: 10px;}.control-footer{margin-top: 10px;text-align: right;}.NewsletterSubscribeForm .email { margin-bottom: 0px; }.NewsletterSubscribeForm .unsubscribe { text-align: right; }html, body{background: #222222;margin: 0px;margin-top: 50px;margin-bottom: 100px;}#main-top, #main-bottom{color: #c4c4c4;}#main-top{padding-bottom: 50px;background-position: bottom;background-repeat: repeat-x;background-image: url(../../../img/themes/pro/bg_top.jpg);}#main-logo{padding: 0px;padding-left: 150px;padding-top: 30px;background-image: url(../../../img/themes/pro/logo.gif);background-repeat: no-repeat;}.main-width{width: 900px;margin: 0 auto;}#main-content { background: white; }#main-content-left { width: 210px; }#main-content-middle { width: 412px; }#main-content-right { width: 220px; }#main-content-left,#main-content-middle,#main-content-right{padding-left: 10px;padding-right: 10px;}#main-content-left, #main-content-right {border-left: solid 1px #cccccc;border-right: solid 1px #cccccc;}#main-bottom{padding-top: 60px;background-position: top;background-repeat: repeat-x;background-image: url(../../../img/themes/pro/bg_bottom.jpg);}#main-bottom-left, #main-bottom-right{color: white;font-size: 0.82em;}#main-bottom-left{padding-right: 10px;border-right: solid 1px #000000;}#main-bottom-right{padding-left: 10px;border-left: solid 1px #333333;}html, body{color: #333333;font-family: Helvetica, Tahoma, Arial, sans-serif, Verdana, Geneva;font-size: 0.9em;}a{color: #ff9900;font-weight: bold;text-decoration: none;}a:hover { color: #ffbb00; }a, ul a { outline: none; }form{padding: 0px;margin: 0px;}h1{font-size: 1.65em;}h2{font-size: 1.4em;margin-top: 25px;border-bottom: solid 1px #cccccc;}h3{margin-top: 25px;margin-bottom: 10px;}h1, h2, h3 { color: #444444; }h1, h2.first, h3.first { margin-top: 0px; }h1.nospace, h2.nospace, h3.nospace { margin-bottom: 0px; }img, a img{border: none}table{border-collapse: collapse;}table td{padding-right: 5px;vertical-align: top;}.grid {}.grid .row {}.grid .row .cell { float:left; width: 100%; }.grid .row.one .cell { float:none; width: 100%; }.grid .row.two .cell { width:50%; }.grid .row.three .cell { width:33.2%; }.grid .row.four .cell { width:25%; }.grid .row.five .cell { width:20%; }.grid .row.six .cell { width:16.6%; }.grid .row.seven .cell { width:14.2%; }.grid .row.eight .cell { width:12.5%; }.grid .row.nine .cell { width:11.1%; }.grid .row.ten .cell { width:10%; }.grid .row, .grid .row .cell.last { overflow: hidden; }.grid .row .cell.last { float:none; width:auto; }.grid.border .row { border-top: solid 1px black; }.grid.border .row.last { border-bottom: solid 1px black; }.grid.border .row .cell { border: none; border-left: solid 1px black; }.grid.border .row .cell.last, .grid.border .row.one .cell { border-right: solid 1px black; }ul.horizontal,#main-menu ul, #main-bottom ul,#main-content-middle ul.titleMenu,#main-content-middle ul.images{margin: 0px;padding: 0px;list-style: none;}ul.horizontal li,#main-menu ul li, #main-bottom ul li,#main-content-middle ul.titleMenu li,#main-content-middle ul.images li{display:inline;}ul.vertical-list,#main-subMenu ul, #main-content-middle ul{border-top: solid 1px #cccccc;margin: 0px;padding: 0px;list-style: none;}ul.vertical-list li,#main-subMenu ul li, #main-content-middle ul li{border-bottom: solid 1px #cccccc;margin: 0px;padding: 5px;}ul.vertical-list li.even,#main-subMenu ul li.even, #main-content-middle ul li.even{background-color: #f3f3f3;}ul.vertical-list li.selected,#main-content-middle ul li.selected{border-bottom: solid 1px #bbbbbb;background-color: #eaeaea;}ul.vertical-list li.separator,#main-subMenu ul li.separator, #main-content-middle ul li.separator{font-size: 0.1em;background: url(../../../img/themes/pro/bg_lines.gif);}ul.vertical-list li:hover,#main-subMenu ul li:hover, #main-content-middle ul li:hover{background-color: #f9f9f9;}#main-menu li{font-size: 1.5em;font-weight: bold;}#main-menu li { margin-right: 10px; }#main-menu li a { margin-right: 5px; }#main-bottom li { margin-right: 5px; }#main-bottom li a { margin-right: 3px; }#main-menu li a, #main-subMenu li a, #main-bottom li a { text-decoration: none; }#main-menu li a, #main-bottom li a { color: white; }#main-subMenu li a { color: black; }#main-subMenu li a, #main-bottom li a { font-weight: normal; }#main-menu li.selected a, #main-subMenu li.selected a, #main-menu li a:hover, #main-subMenu li a:hover, #main-bottom li a:hover, #main-bottom li.section, #main-bottom li a.more{color: #ff9900; }#main-subMenu li.selected{background-image: url(../../../img/themes/pro/bg_subMenu_selected.gif);background-repeat: no-repeat;}#main-subMenu li.selected a{font-weight: bold;padding-left: 5px;}#main-bottom li.section { width: 90px; }#main-bottom li.section, #main-bottom li a.more { font-weight: bold; }#main-content-middle ul.titleMenu{padding:5px;padding-top:7px;margin:0px;margin-top: 10px;text-align: center;background-color: #f8f8f8;border-bottom: solid 1px #cccccc;}#main-content-middle ul.titleMenu li,#main-content-middle ul.titleMenu li:hover{background: none;padding: 10px;border-bottom: none;}#main-content-middle ul.titleMenu li a{color: #505050;}#main-content-middle ul.titleMenu li a:hover{color: #ff9900;}#main-content-middle ul.images{border: none;text-align: center;}#main-content-middle ul.images li,#main-content-middle ul.images li:hover{padding: 5px;border-bottom: none;}#main-content-middle ul.images img{padding: 3px;border: solid 1px #cccccc;}#main-content-middle ul.images img { margin-bottom: 8px; }#main-content-middle ul.songs, ul.songs{margin-top: 10px;}ul.songs li,ul.songs li:hover{line-height: 23px;padding: 0px;padding-top: 4px;}ul.songs li span { float: right; }#lbOverlay {position: fixed;z-index: 9999;left: 0;top: 0;width: 100%;height: 100%;background-color: #000;cursor: pointer;}#lbCenter, #lbBottomContainer {position: absolute;z-index: 9999;overflow: hidden;background-color: #fff;}.lbLoading {background: #fff url(../../../img/slimbox/loading.gif) no-repeat center;}#lbImage {position: absolute;left: 0;top: 0;border: 10px solid #fff;background-repeat: no-repeat;}#lbPrevLink, #lbNextLink {display: block;position: absolute;top: 0;width: 50%;outline: none;}#lbPrevLink {left: 0;}#lbPrevLink:hover {background: transparent url(../../../img/slimbox/prevlabel.gif) no-repeat 0 15%;}#lbNextLink {right: 0;}#lbNextLink:hover {background: transparent url(../../../img/slimbox/nextlabel.gif) no-repeat 100% 15%;}#lbBottom {font-family: Verdana, Arial, Geneva, Helvetica, sans-serif;font-size: 10px;color: #666;line-height: 1.4em;text-align: left;border: 10px solid #fff;border-top-style: none;}#lbCloseLink {display: block;float: right;width: 66px;height: 22px;background: transparent url(../../../img/slimbox/closelabel.gif) no-repeat center;margin: 5px 0;outline: none;}#lbCaption, #lbNumber {margin-right: 71px;}#lbCaption {font-weight: bold;}

    This is great, right? Nice, clean and compact.

    However, this approach – which can be found in various CSS bundle solutions around the web – suffers from a major flaw…file paths. Since the virtual file most probably does not exist at the same folder level in the file system as the parsed files, all paths in the bundle file will be invalid. This is especially true when parsing files from many different folders.

    The approach above requires you to either use absolute paths in your css files or have the css files at the same folder level in the file system as the bundle file. This is not always applicable, especially since I want to allow developers to point out any folder as css folder.

    It is possible, though, by providing the bundle file with various file system information, to acount for the path differences and change the file paths so that they work within the bundle file. This, however, involves way too much work and testing for me to be interested in implementing such a solution…at least now.

    So, I have now taken a step back. The bundle file still remains, but instead of adding all file content to the output as above, I simply import all files of interest into it. The virtual file output will thus look something like this:

       @import url("../css/default.css");@import url("../../wigbi/css2/x.css");@import url("../../wigbi/css2/y.css");

    This is not as fast as the compact first option, since I have no possibility of compressing the CSS code. However, but by linking to the CSS files like this, I do not have to account for file paths within each file. It works automatically…like a charm 🙂

  • danielsaidi 7:03 am on May 26, 2010 Permalink | Reply
    Tags: dirname, , __file__   

    Include and require files within included files in PHP 

    Today, I noticed this nice piece of code within the SimpleTest autorun.php file.

       require_once dirname(__FILE__) . '/unit_tester.php';

    Finding the folder of the current file, and not the executing file, is extremely useful when including/requiring files within files that are included by another page.

    When using dirname(__FILE__), the require operation works relative autorun.php, even if the file is included by another page. If this would not have been used, the page would have tried to look for the unit_tester.php file relative the including file, which would not have worked.

    I have previously solved this kind of folder issues with an “application root” path, but this is also a very nice approach.

    Thank you SimpleTest.

  • danielsaidi 11:17 pm on May 24, 2010 Permalink | Reply
    Tags: multiple, mysql, mysql_connect   

    Multiple mySQL database connections in PHP 

    As I am working on my hobby project Wigbi, I am making it possible to create multiple instances of the DatabaseHandler class, to make it possible to work with multiple databases.

    However, as I shut down one connection, I noticed that all connections were closed. When I investigated the issue further, I realized that even though I created multiple connections, I only had one.

    So, why did I only receive one single connection, although I created multiple ones? The answer lies in the fourth parameter that is sent to the mysql_connect function. If this is not set to true, multiple connections will not be allowed.

    • Matt Smith 4:02 am on January 7, 2011 Permalink | Reply

      You’re right Daniel. Not a big deal, but a great reminder. I almost never use multiple connections in my systems, but when building a system that runs along side another, like WordPress, this is important to prevent a conflict. In fact, that’s my situation tonight, and your blog gave me the reminder I needed about the 4th parameter. Thanks.

      • danielsaidi 11:46 pm on January 10, 2011 Permalink | Reply

        Glad to help, Matt, and thanks for commenting so that I was reminded of this as well 🙂

    • Ray Sterling 5:29 am on February 17, 2012 Permalink | Reply

      Matt, I am trying to connect to a second database that would hold some information for my website running through wordpress as well… How have you accomplished connecting to a second database in order to run queries from that database and present the data in your wordpress site? — Thanks for any help you can supply.

  • danielsaidi 11:43 pm on April 26, 2010 Permalink | Reply
    Tags: ,   

    SimpleTest – Test Driven Development in PHP 

    In my daily work, working with .NET/C#, I love the way TDD and NUnit simplifies my work and allows me to focus on implementation instead of worrying about whether or not my new code will break anything already existing.

    When I develop PHP applications at home, however, I have not previously had any natural way of testing my code, since I have not had any good tool for testing my PHP code…and have not really put any effort into finding any such tool either.

    Today, however, this has changed. After starting developing Wigbi 1.0.0, I decided to browse the web and instantly found my dream tool – SimpleTest (can be downloaded at http://simpletest.org).

    It took me less than 5 minutes to download SimpleTest and use it to run my first test. It is simple (duh) and plain fantastic. If you are not into TDD, I strongly advice you to try it out…test is bliss.

Compose new post
Next post/Next comment
Previous post/Previous comment
Show/Hide comments
Go to top
Go to login
Show/Hide help
shift + esc