Node.js scalability and tech writers

I’ve just published a text on the LoadImpact blog. This time I write a little bit about the findings I made when trying to put a little heavier load on a very simple Node.js, turns out that Node.js is not a silver bullet after all. Who would have guessed.

If you need content for your blog or magazine. I’m available as a guest writer. I write mostly about coding, web standards, open source technology and similar subjects. Don’t hesitate to contact me if you have questions or if you want to get a quote.

 

LoadImpact

1-loadimpact

I’ve just started blogging as a guest writer at LoadImpact.com. If you’re not already familiar with LoadImpact, go check them out. They provide the word leading load test as cloud service solution and is free to try out.

Today my first post was published about the difference between Node.js and PHP as server side languages/environments.

So, get out of here already and read about it.

Debugging your phpunit test cases in CodeIgniter

I don’t know why it feels ironic, but it does. Sometimes I need to debug my phpunit test cases and it wasn’t very very self explanatory to understand how to set it up . The solution however, is quite easy.

I’ve previously written about how to enable the php debugger xdebug from a command line script. The end result from reading that article should be that you have a php5d command on your system that will trigger xdebug to hook into your IDE (mine is Sublime Text 2, yours may differ). For the rest of this article, I’m going to assume you have the php5d command available.

Next step is to prepare your test classes for execution via a php command rather than via the phpunit framework (don’t worry, it will be included). The solution to this was found at Stack Overflow (naturally, read it, it’s good), but I  found out that two simplifications can be made when used in CodeIgniter with CI_Unit.

The foundation of the StackOveflow trick is to make sure that a couple of PHPUnit classes are loaded, either via explicit statements as the sample suggests, or via the PHPUnit/Autoload functionality. Turns out that when bootstraping PHPUnit via CI_Unit, it already brings in PHPUnit/Autoload.php. That makes it one less requre_once statement to forget about.

The second simplification is to minimize the room for copy / paste related errors. As long as you are a bit obsessive with class names and make sure that your file name is always classname.php (so class FooTest is implemented in the file FooTest.php), then you can avoid typing the class name in one additional place. That’s exactly what I need to do myself to avoid hard to catch errors.

My test cases are now modeled after this template:

<?php
/**
* Tests for the Foo class
*/
require_once('../application/third_party/CIUnit/bootstrap_phpunit.php');

class FooClassTest extends CIUnit_TestCase
{
static function main() 
{
  $suite = new PHPUnit_Framework_TestSuite( __CLASS__);
  PHPUnit_TextUI_TestRunner::run( $suite);
}

public function setUp()
{

}

public function testSomething()
{
  $this->assertTrue(FALSE);
}
}

if (!defined('PHPUnit_MAIN_METHOD')) {
  $class = str_replace('.php','', basename(__FILE__));
  $class::main();
}

And to actually debug it (assuming that the above test class is stored in tests/lib and is naturally named FooClassTest.php), I type:

$ cd tests
$ php5d libs/FooClassTest.php

And to run it under PHPUnit, it’s works just as you’re used to already.

/E

Using CodeIgniter migrations with PHPUnit

Even some of the CodeIgniter developers are not especially happy about how Migrations are implemented in the current version. Never the less, if you have a CodeIgniter 2.x code base that you want to write unit tests for, you may want to use them.

In a PHPUnit test class, you can use setUp() and tearDown() methods to prepare, run fixtures, create mock objects or whatever else you need to do. Since testing always should be targeted at a test database, one of the things I do is to run migrations. In the setUp() method, I execute migrations to create tables and insert data, in the tearDown() function, I do the opposite. Something like this:

public function __construct($name = NULL, array $data = array(), $dataName = '')
{
	parent::__construct($name, $data, $dataName);
	$this->CI->load->library('migration');
}

public function setUp()
{
	this->CI->migration->version(3);
}

public function tearDown()
{ 
	$this->CI->migration->version(0);
}

Please note: Calling migrations from the setUp() or tearDown() functions may or may not be a very bright idea. It depends a lot on how you organize your tests. setUp() and tearDown() are called once before/after every individual test function in your test class, so static methods setUpBeforeClass() and tearDownAfterClass() may be a lot better:

class InflowLibTest extends CIUnit_TestCase
{
	static public function setUpBeforeClass()
	{
		$CI =& get_instance(); 
		$CI->load->library('migration');
		// Also, make sure that the test db is up to the correct level:
		$CI->migration->version(0);
		$CI->migration->version(1);
	}

	static public function tearDownAfterClass()
	{
		$CI =& get_instance(); 
		$CI->load->library('migration');
		// Tear it down.
		$CI->migration->version(0);
	}

Anyway, I discovered that in the current version,  CodeIgniter Migrations doesn’t do this vey well. The problem is in system/libraries/Migration.php. Line 160 in my file (version 2.1.3), but line 227 in the current Github version.

// Cannot repeat a migration at different steps
if (in_array($match[1], $migrations))
{
$this->_error_string = sprintf($this->lang->line('migration_multiple_version'), $match[1]);
return FALSE;
}

include $f[0];
$class = 'Migration_' . ucfirst($match[1]);

if ( ! class_exists($class))
{
$this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class);
return FALSE;
}

$f[0] is the variable holding the name of the Migration file to load and execute next. Problem is that that line assumes that the file in question isn’t already loaded. Probably an OK assumption in most cases. But when running in context of PHPUnit the way I do it, both setUp() and tearDown() will be run in the same PHP session. So the second time around, when tearDown() executes, all the migration modules will already be included into the PHP process. Simply changing include into require_once fixes the problem. The resulting code should look like this

// Cannot repeat a migration at different steps
if (in_array($match[1], $migrations))
{
$this->_error_string = sprintf($this->lang->line('migration_multiple_version'), $match[1]);
return FALSE;
}

require_once $f[0];
$class = 'Migration_' . ucfirst($match[1]);

if ( ! class_exists($class))
{
$this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class);
return FALSE;
}

 

Enjoy,

 

/E

 

[tags2products]

Debug PHP-cli scripts with Xdebug and Sublime Text 2

In my previous post, I explained how I’ve set up debugging PHP scripts with Xdebug and Sublime Text  2 in a web based environment. In this part, I’ll outline how I debug PHP command line scripts.

If you want to follow this guide, make sure you have everything setup as explained in the previous post.

Triggering Xdebug

When using Xdebug from a web browser, I use the Chrome extension Xdebug Helper to send a valiid XDEBUG_CONFIG parameter string to the PHP process. The magic part is to set the idekey parameter to sublime.xdebug (sent via the cookie). To do the  same thing when running a script from the command line, the magic trick is to use the environment variables. This is explained in the Xdebug manual, like this:

export XDEBUG_CONFIG="idekey=session_name"
php myscript.php

Oh, how cumbersome to type. Let’s do that in a script instead. Create a file php5d like this:

#!/bin/sh
export XDEBUG_CONFIG="idekey=sublime.xdebug"
php5 $@

Make the file executable:

chmod +x php5d

Then give it a try, let’s debug the test script we created in the previous post, test.php:

  1. Open test.php in Sublime Text 2
  2. Start a debugging session by hitting Shift+F8
  3. Set a breakpoint on a suitable line (must be a non-blank line)
  4. Run the script: php5d test.php

You should see something like this:

Debugging_sublime

One last thing

With the php5d script in place, it’s easy and straight forward to debug command line scripts without doing too much damage on the normal environment. The last thing I did in my environment was to put the script in my /home/erik/bin folder to make it callable from everywhere on my machine:

Make sure I’ve got a central place for your personal scripts. At the end of your ~/.bashrc, make sure you have a line like this (you may already have something similar in place, I’m using subfolder bin, you may use something else):

## Additional personal scripts etc.
PATH=$PATH:"~/bin"

Then, copy the php5d script to the intended folder:

mv php5d ~/bin

And reload .bashrc (or just start a new terminal window)

. .bashrc

There you go, a globally available php5d command that triggers debugging in Sublime Text 2 for whatever PHP script you launch. Enjoy

/E

 

 

 

 

CodeIgniter for PHP CodeSniffer gets better

Just a quick note, my PHP CodeSniffer standard for CodeIgniter improves gradually, since I originally mentioned it a month ago, the following improvements have been made to the repo:

  1. Improved indentation checks in switch statements, works with tabs now
  2. Correct file and class naming when creating libraries (CodeIgniter expects capitalized file names for libraries)
  3. Support for accepting a range of short (less than 4 characters) variable names. Common and meaningful names such as $sql, $id, $ret etc.
  4. (kind of a hack) Accept the public function name _init(). Only because it’s a requirement when using GasOrm.

So, go update your installations, all 3 of you 🙂

/Erik

Debugging PHP with Sublime Text 2

In my early days of developing, I was heavily using Microsoft Visual Studio almost exclusively and say what you want about developing in the Microsoft ecosystem, but debugging Just Worked. In the Open source world of various iteration of LAMP stack, debugging is more of a challenge and honestly, just as many other developers working with PHP, I quite often just decide to live without step-by-step debugging.

However, on my latest development machine, I did make the effort and put all the pieces together and as much as I want to share, this blog post mostly serves as a memory backup knowledge for myself.

Part list

A little bit about my environment:

  • My development machine is a laptop with Ubuntu 12.10 on it. Most of these instructions should work just fine on most other Linux distros as well.
  • I use Sublime Text 2 as my primary code editor. I like it a lot and I also selected it partly it can do debugging. (and yes, I did shell out the money for a license, suggest you do the same if you use it daily)
  • In Sublime Text 2, I’m using Kindaris Sublime Xdebug client
  • I have Apache2 installed on this development machine, but I have selected not to to enable Xdebug in apache2. Instead, I use PHP built in webserver (introduced in php 5.4) when I want to debug in the code.
  • I’m using Xdebug as the actual debugger.
  • To trigger debugging, I use the chrome extension Xdebug helper

Getting started

Here we go

Installing Sublime Text 2

(read more about Sublime Text 2)

Depending on your precise environment, how and where you install Sublime Text may vary. On Ubuntu 12.10, the by far easiest way is to get it via the http://www.webupd8.org/ like this:

$ sudo add-apt-repository ppa:webupd8team/sublime-text-2;
$ sudo apt-get update;
$ sudo apt-get install sublime-text

INSTALLING XDEBUG

Getting it onto the machine should be very straight forward:

$ sudo apt-get install php5-xdebug

So, but I had this minor itch that I wanted to scratch. Even if this is my development machine, I’d like to keep Xdebug out of the Apache2 installation, instead, I want to do my debugging via the built in PHP web server, to me that makes more sense.

After Xdebug is installed, it also updates php5 configuration on the box so that it’s globally available, so regardless if you run php from Apache2 and from command line. This is achieved by a little symlink magic. The content of my /etc/php5/conf.d directory:

lrwxrwxrwx 1 root root 25 Nov 13 11:36 10-pdo.ini -> ../mods-available/pdo.ini
lrwxrwxrwx 1 root root 26 Dec 11 15:29 20-curl.ini -> ../mods-available/curl.ini
lrwxrwxrwx 1 root root 24 Nov 19 02:25 20-gd.ini -> ../mods-available/gd.ini
lrwxrwxrwx 1 root root 28 Nov 13 15:20 20-mysqli.ini -> ../mods-available/mysqli.ini
lrwxrwxrwx 1 root root 27 Nov 13 15:20 20-mysql.ini -> ../mods-available/mysql.ini
lrwxrwxrwx 1 root root 31 Nov 13 15:20 20-pdo_mysql.ini -> ../mods-available/pdo_mysql.ini
lrwxrwxrwx 1 root root 28 Dec 26 17:46 20-xdebug.ini -> ../mods-available/xdebug.ini

On my fairly new Debian based distribution, the correct way to remove Xdebug from the /etc/php5/conf.d folder is:

$ sudo php5dismod xdebug

But if you don’t have the php5enmod / php5dismod commands, you may just as well just delete the symlink using rm:

$ rm /etc/php5/conf.d/xdebug.ini

With Xdebug out of the global config, you want to add it to the config for cli. So in the file /etc/php5/cli/php.ini, you add at the very end:

[xdebug]
zend_extension=/usr/lib/php5/20100525/xdebug.so
xdebug.remote_enable=On
xdebug.remote_host="localhost"
xdebug.remote_port=9001
xdebug.remote_handler="dbgp"

So, now Xdebug is available only when php is run via the command line and not via Apache2.

Installing Sublime Text package control

By far the easiest way to get various Sublime Text packages installed is to use the package manager Package Control. It’s a full-featured package manager that helps discovering, installing, updating and removing packages for Sublime Text 2. It features an automatic upgrader and supports GitHub, BitBucket and a full channel/repository system.

Installation is extremely easy via the Sublime Text console. In Sublime, you either select View -> Show Console or via the shortcut Ctrl+’. In the console, paste the following command:

import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'

Once you restart Sublime Text 2, you should have ‘Package Control’ in the Preferences menu. Read more about installing and trouble shooting Package Control here.

Installing Kindaris Sublime Xdebug

Finally, almost the last piece of software to install. Kindari’s Sublime Xdebug client. In Sublime Text 2 go to the preference menu and select Package Control => Install package. You should see something like this:

PackageControl_1

Now, select Install Package and type xdebug. The search function should more or less immediately give you Xdebug – Xdebug Interface for Sublime… as an option. Just select it and let the installation begin. There. Done. Almost.

INSTALLING Python 2.6 packages

Xdebug Interface for Sublime depends on a package from Python 2.6, so to get it to work on your machine, chances are that you need to install Python 2.6. On later releases of Ubuntu, it’s not possible to install Python 2.6 via the repos. But there is a fairly easy way to get the package we miss:

  1. Download Python 2.6 from the Ubuntu archives
  2. Extract Python 2.6 under the Sublime Text lib folder
  3. Clean up

Like so (if you’re on a 64 bit machine):

$ wget http://security.ubuntu.com/ubuntu/pool/main/p/python2.6/python2.6_2.6.5-1ubuntu6.1_amd64.deb
$ dpkg-deb -x python2.6_2.6.5-1ubuntu6.1_amd64.deb python2.6_2.6.5
$ sudo cp -r python2.6_2.6.5/usr/lib/python2.6 /usr/lib/sublime-text-2/lib/
$ rm -rf python2.6_2.6.5
$ rm -rf python2.6_2.6.5-1ubuntu6.1_amd64.deb

And like this if you’re on a 32 bit machine, it should work like this, however I never tried it:

$ wget http://security.ubuntu.com/ubuntu/pool/main/p/python2.6/python2.6_2.6.5-1ubuntu6.1_i386.deb
$ dpkg-deb -x python2.6_2.6.5-1ubuntu6.1_i386.deb python2.6_2.6.5
$ sudo cp -r python2.6_2.6.5/usr/lib/python2.6 /usr/lib/sublime-text-2/lib/
$ rm -rf python2.6_2.6.5
$ rm -rf python2.6_2.6.5-1ubuntu6.1_i386.deb

 

Last piece – Xdeubg Helper for Chrome

With the above pieces in place, Xdebug is really good to go. However, to get Xdebug to work, you need a way to trigger it and the most common (or at least easiest) way to do it for web development is via Xdebug remote debugging. To trigger the debugger, get your web browser to send an additional parameter XDEBUG_SESSION with a value that matches a predefined string in your IDE. You can send the additional parameter as a GET    query parameter, but that will quicky get complicated and / or cumbersome depending on your URL structure. With the XDEBUG Helper extension for Chrome, you force Chrome to send that additional parameter in the background whenever you need it to.

Go to the Chrome Web Store and search XDEBUG Helper in the Extensions section and then add it to chrome. Then go to the Options screen for the extension and add sublime.xdebug as the IDE key. Optionally, you may also want to white list your own machine in the Domain filter section. By doing that, the XDebug helper icon will only show up when you’re surfing on a page that you can actually debug on. Below is my options screen (click to enlarge):

Screenshot from 2012-12-26 23:16:25

Test time

All the pieces are in place, let’s try to do a simple debug session.

1. Create a script to debug

<?php

$foo = array('Abba' => 'Sweden', 'Beatles' => 'England', 'Beach Boys' => 'USA');

foreach($foo as $k => $v)
{
echo "Band {$k} \t Country {$v}\n";
}

2. Launch a PHP webserver. In a terminal window, navigate to the folder where you saved the script above and type:

$ php -S localhost:8000
PHP 5.4.6-1ubuntu1.1 Development Server started at Wed Dec 26 23:44:16 2012
Listening on http://localhost:8000
Document root is /home/erik/src
Press Ctrl-C to quit.

3. In Sublime Text, set a breakpoint on a suitable line (note: can’t be a blank line) by putting the cursor on that line and hit Ctrl+F8, you should see a round marker in the left margin.

4. In Sublime Text, enter debug mode by hitting Shift+F8 and select ‘Start Debugging’ from the menu that appears.

5. In Chrome, surf to http://localhost:8000/test.php. Click on the gray ‘bug’ icon in the address field to make it grren. Then refresh the page again

Xdebug-for-chrome

6. Hey presto!!!! In Sublime, you should now see a small triangle on the first line with a break point that indicates that it’s the next line to be executed.

Debugging_sublime

You are now debugging your code inside Sublime Text 2.

Shortcut keys

  • Shift+f8: Open XDebug quick panel
  • f8: Open XDebug control quick panel when debugger is connected
  • Ctrl+f8: Toggle breakpoint
  • Ctrl+Shift+f5: Run to next breakpoint
  • Ctrl+Shift+f6: Step over
  • Ctrl+Shift+f7: Step into
  • Ctrl+Shift+f8: Step out

Trouble shooting

I’ve only had one real problem setting this up on my machine. When I first tried this, the sublime xdebub panels ‘Context’ and ‘Stack’ would stay blank and the debugger refused to connect to the IDE. The problems turned out to be that I missed the Python 2.6 packages mention above. So make sure not to skip the section ‘Installing Python 2.6 packages’ above.

To finish of, go to https://github.com/Kindari/SublimeXdebug to read more about the tool and then, enjoy.

 

/E

 

 

 

 

 

Net ID on Ubuntu 12.10

I don’t know if it’s because of my desktop environment (Ubuntu 12.10, Gnome Shell 3.6) is so darn special or because Firefox 17 disabled a certain feature. But anyway, when I tried installing Net ID from SecMaker, better known as Telia e-legitimation, it would just fail. But I was able to find a workaround.

My symptoms: I followed the instructions from Telia / SecMaker and it semed OK. To finish the actual installation part, you’re supposed to browse to /etc/iid/pkcs11.html to let Firefox install Net ID as a local security device. However, that part simply doesn’t work. I got the message:

 

Installation status for Net iD pkcs#11 module is unknown, use buttons below to install or uninstall the module.

But the buttons Install / Uninstall didn’t actually do anything.

  1. The problem: The whole point of surfing to /etc/iid/pksc11.html is so that a javascript can install Net ID as security device. Turns out that Firefox 17 have disabled access to the internal Firefox object that can manipulate the list of security devices unless the code executes inside a proper Firefox extension. In this case, the code executes inside a normal webpage so it simply won’t work.

The solution: It turns out that there’s another method to install Net ID as a security device and that  is to do it manually. This is how.

1. Open Edit -> Preferences -> Advanced.

2. Select the Encryption tab

3. Click Security Devices. You should see something like the below (except that you won’t see “Net ID” in the tree view on the left hand side.Screenshot from 2012-12-18 10:08:57

4. Click the Load button on the right hand side. Fill in the details. You want to name the module “Net ID” and give the path to the .so file to /usr/lib/libiid11p.so

Screenshot from 2012-12-18 10:14:44

5. Click OK. You should now see Net ID in the tree view on the left hand side and that’s our goal here, so, hooray!!!

Now, you have added the Net ID software to your computer and made it available in Firefox, so you installation can continue as described in the instructions from Teliea (or whatever ID provider you have).

Good luck!

PHP CodeSniffer and CodeIgniter

I recently found out that Thomas Ernest have created a CodeIgniter standard for CodeSniffer. He mentioned on the CI formus that it’s not perfect and does spit out a few warnings and errors for things that are really OK in the CI style guide. False positives.

This is the slightly modified welcome.php controller file I wanted to scan. According to my understanding of the CodeIgniter style guide, it should pass with flying colors:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* File: welcome.php
* 
* PHP version 5
*
* @category Frontend
* @package  Citest
* @author   Erik Torsner <erik@torgesta.com>
* @license  torgesta.com http://www.torgesta.com/  
* @link     http://www.torgesta.com/  
*/

/**
 * Class Welcome
 *
 * @category Frontend
 * @package  Citest
 * @author   Erik Torsner <erik@torgesta.com>
 * @license  torgesta.com http://www.torgesta.com/
 * @link     http://www.torgesta.com/  
 **/
class Welcome extends CI_Controller {
	/**
	 * Index Page for this controller.
	 *
	 * Maps to the following URL
	 * 		http://example.com/index.php/welcome
	 *	- or -  
	 * 		http://example.com/index.php/welcome/index
	 *	- or -
	 * Since this controller is set as the default controller in 
	 * config/routes.php, it's displayed at http://example.com/
	 *
	 * So any other public methods not prefixed with an underscore will
	 * map to /index.php/welcome/<method_name>
	 *
	 * @see http://codeigniter.com/user_guide/general/urls.html
	 * @return void
	 */
	public function index()
	{
		$this->load->view('welcome_message');
	}
}

/* End of file welcome.php */
/* Location: ./controllers/welcome.php */

See? File doc comment, class doc comment, function doc comment, no PHP end tag but the two standard comments instead. Beautiful. But scanning with CodeSniffer, I’d get something like this:

$ phpcs --standard=CodeIgniter welcome.php 

FILE: /home/foo/src/citest/application/controllers/welcome.php
--------------------------------------------------------------------------------
FOUND 3 ERROR(S) AFFECTING 3 LINE(S)
--------------------------------------------------------------------------------
  1 | ERROR | Missing file doc comment
 47 | ERROR | Multi lines comments are not allowed; use "// Comment" DocBlock
    |       | comments instead
--------------------------------------------------------------------------------

Time: 0 seconds, Memory: 3.25Mb

First problem, CodeSniffer doesn’t see the file doc comment at all. Turns out the CodeSniffer looks for the first non white space token after the PHP open tag. If it’s a valid file doc comment, all is good. In CodeIgniter, the standard behavior is to add a check for “BASEPATH” right at the top and it gets in the way of finding the existing file doc comment.

Second problem. CodeIgniter style guide first say that all code comments should be one line comments. A few examples:

<?php

// One line comment using '//'. Fine with CodeIgniter 
$foo = "bar";

/*One line comment using '/*', not OK */
$fuu = "bar";

// Multi line comments, you should still use '//'
// This is the next comment line
$fuubar = NULL:

/* Multi line comments, this way is not OK
*This is the next comment line */
$fuubar = 42:

// But wait! at the end of the file. CI expects this:
// Two single line comments using '/* ... */. 
/* End of file welcome.php */
/* Location: ./controllers/welcome.php */

This is simply not consistent. To get clean scans using CodeSniffer, you have two options. Rewrite all end-of-file comments to use ‘//’ rather than ‘/*’ or fix CodeSniffer. Even if consistency is a good thing, this is a very well established style in CodeIgniter so I was inclined to fix CodeSniffer rather than fight.

The CodeSniffer standard is installed (on Ubuntu) in

/usr/share/php/PHP/CodeSniffer/Standards/CodeIgniter

 

To fix the comments, I made the following change to

/usr/share/php/PHP/CodeSniffer/Standards/CodeIgniter/Sniffs/Commenting/InlineCommentSniff.php

 

    private function _checkCommentStyle(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        $cmt = $tokens[$stackPtr]['content'];
        if($this->beginsWith($cmt, '/* End of file')) return TRUE;
        if($this->beginsWith($cmt, '/* Location:')) return TRUE;
        ...
        ...

That it, to explicitly allow the two CodeIgniter specific comments. The second change was bigger. The CodeIgniter standard for CodeSniffer reuses PEAR’s check for file doc comments. Rather than modifying what is a built in CodeSniffer standard, I copied the correct file to the CodeIgniter standard and made modifications there. So I created the file

/usr/share/php/PHP/CodeSniffer/Standards/CodeIgniter/Sniffs/Commenting/FileCommentsSniff.php

 

as a copy of the corresponding file from the PEAR standard. Function process was modified:

    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $this->currentFile = $phpcsFile;

        // We are only interested if this is the first open tag.
        if ($stackPtr !== 0) {
            if ($phpcsFile->findPrevious(T_OPEN_TAG, ($stackPtr - 1)) !== false) {
                return;
            }
        }

        $tokens = $phpcsFile->getTokens();

        // Allow CodeIgniter std "if ( ! defined('BASEPATH')).... on the first line
        // keep iterating until we find a token on line 2...
        $startLine = $tokens[$stackPtr]['line'];
        $lastToken = $stackPtr;
        while($tokens[$lastToken+1]['line'] == $startLine) {
          $lastToken++;
        }

So, a simple loop that simply ignores whatever tokens that  is on the same line as the PHP open tag. Simple and it works. The last change I made was in

/usr/share/php/PHP/CodeSniffer/Standards/CodeIgniter/ruleset.xml

 

where the rule that refers to the FileCommentSniff file is modified so that it looks at the local copy rather than the one from the PEAR standard. Just change the line:

<rule ref="PEAR.Commenting.FileComment">

Into

<rule ref="CodeIgniter.Commenting.FileComment">

That’s it. A new test scan reveals that the perfectly decent looking welcome.php doesn’t generate any further errors:

$ phpcs --standard=CodeIgniter welcome.php 
Time: 0 seconds, Memory: 3.25Mb

Now, go to github and get the repo.