<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>King Kludge &#187; code analysis</title>
	<atom:link href="http://www.kingkludge.net/tag/code-analysis/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kingkludge.net</link>
	<description>Husband, father, hacker, maker. Addicted to all things geeky, especially robots.</description>
	<lastBuildDate>Wed, 28 Sep 2011 14:18:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>The CodeSniffer Series</title>
		<link>http://www.kingkludge.net/2009/08/the-codesniffer-series/</link>
		<comments>http://www.kingkludge.net/2009/08/the-codesniffer-series/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 21:04:55 +0000</pubDate>
		<dc:creator>Bob</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Yahoo!]]></category>
		<category><![CDATA[code analysis]]></category>
		<category><![CDATA[codesniffer]]></category>
		<category><![CDATA[standards]]></category>

		<guid isPermaLink="false">http://www.kingkludge.net/2009/08/the-codesniffer-series/</guid>
		<description><![CDATA[Recently I wrote a series of posts about PHP CodeSniffer the PHP PEAR project. This is a brief reminder of the series and a list of all the articles. These articles are the originals and are being used as a &#8230; <a href="http://www.kingkludge.net/2009/08/the-codesniffer-series/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently I wrote a series of posts about PHP CodeSniffer the PHP PEAR project.</p>
<p>This is a brief reminder of the series and a list of all the articles.</p>
<p>These articles are the originals and are being used as a base for a <a title="Yahoo Developers Network" href="http://developer.yahoo.com">YDN</a> article to be published shortly.</p>
<ol>
<li><a href="/2009/01/codesniffer-part-1-introduction-to-codesniffer/">Introduction to CodeSniffer</a> </li>
<li><a href="/?p=62">CodeSniffer Output</a> </li>
<li><a href="/2009/02/codesniffer-part-3-writing-an-example-codesniffer-standard/">Writing an example CodeSniffer Standard</a> </li>
<li><a href="http://www.kingkludge.net/2009/02/codesniffer-part-4-how-does-codesniffer-work/">How does CodeSniffer work?</a> </li>
<li><a href="http://www.kingkludge.net/2009/08/codesniffer-part-5-writing-an-examples-codesniffer-sniff/">Writing an example CodeSniffer Sniff</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.kingkludge.net/2009/08/the-codesniffer-series/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CodeSniffer Part 5: Writing an examples CodeSniffer Sniff</title>
		<link>http://www.kingkludge.net/2009/08/codesniffer-part-5-writing-an-examples-codesniffer-sniff/</link>
		<comments>http://www.kingkludge.net/2009/08/codesniffer-part-5-writing-an-examples-codesniffer-sniff/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 21:02:20 +0000</pubDate>
		<dc:creator>Bob</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[code analysis]]></category>
		<category><![CDATA[codesniffer]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[static code analysis]]></category>

		<guid isPermaLink="false">http://www.kingkludge.net/2009/08/codesniffer-part-5-writing-an-examples-codesniffer-sniff/</guid>
		<description><![CDATA[How to go about developing your own CodeSniffer Sniff ready for inclusion in a CodeSniffer standard. <a href="http://www.kingkludge.net/2009/08/codesniffer-part-5-writing-an-examples-codesniffer-sniff/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There has been a significant delay between the original posts and this final post in the initial CodeSniffer series, for which I apologise. This delay is mainly due to my recent workload increase, and the happy news that my wife is pregnant coupled with the brief flutter of nesting activity increase at home.</p>
<p><a href="/2009/02/codesniffer-part-4-how-does-codesniffer-work/">In the last post</a> we looked at the internals of CodeSniffer and how the processing of files is done. This time we will look at how an individual Sniff is constructed.</p>
<h3>Sniff Basics</h3>
<ul>
<li>Each <strong>Sniff</strong> is a PHP class.</li>
<li>Each class consist of a minimum of two methods.
<ul>
<li>A register method, that returns an array of tokens that the Sniff is interested in.</li>
<li>And a process method that is executed each time that token is encountered.</li>
</ul>
</li>
<li>Each Sniff class lives inside a <strong>Standard.</strong>
<ul>
<li>Each Sniff lives inside a subfolder &#8220;Sniffs&#8221; under the standard</li>
<li>Each Sniff lives inside a subfolder of &#8220;Sniffs&#8221; containing themed Sniffs</li>
</ul>
</li>
<li>Each Sniff class must adhere to the naming convention.</li>
</ul>
<h3>Starting a Sniff</h3>
<p>Let&#8217;s take a look at an example Sniff. For instance a Sniff designed to check that our PHP code has no extraneous whitespace outside of our PHP code, that could cause a PHP error should we subsequently send headers to the browser.</p>
<p>First of all we create a class and decide on a name for it.</p>
<p>As CodeSniffer uses an autoloader that loads the class&#8217; file and path based on the class name we have to stick to a specific naming convention.</p>
<p><code class="prettyprint">class KingKludge_Sniffs_PHP_NoExtraneousWhiteSpaceSniff<br />
implements PHP_CodeSniffer_Sniff</code><code class="prettyprint"> {}</code></p>
<p>equates to a path of:</p>
<p>{CodeSniffer}/Standards/KingKludge/Sniffs/PHP/NoExtraneousWhiteSpaceSniff.php</p>
<p>where {CodeSniffer} is your CodeSniffer install path.</p>
<p>Secondly, inside our new class we must define our register method:</p>
<pre class="prettyprint">public function register()
{
	return array(
		T_OPEN_TAG,
		T_CLOSE_TAG,
		);
}</pre>
<p>As we want to check for whitespace before or after our PHP declarations, we state that this sniff is interested in PHP open and close tags.</p>
<p>Thirdly, we must define our process method:</p>
<pre class="prettyprint">
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{

}
</pre>
<p>As you can see, our process method is passed some parameters.</p>
<p>These are <code>$phpcsFile</code> which is <code>PHP_CodeSniffer_File</code> object, containing the file being processed and <code>$stackPtr</code> an integer value pointing to CodeSniffer&#8217;s current place in the file.</p>
<p><a title="Empty class file with function definitions only" rel="shadowbox" href="http://github.com/b3cft/kingkludge-codesniffer/raw/3a3334dce2e76441c539d5fd94272c5b3bb0009d/KingKludge/Sniffs/PHP/NoExtraneousWhiteSpace.php">View the empty standard file on GitHub</a></p>
<p>Now on to the actually code in our Sniff.</p>
<p>As our proposed Sniff is going to look for whitespace being output before our page is ready to be rendered, we are interested in whitespace that occurs before the opening PHP tag or after the closing PHP tag.</p>
<p>We are only interested in whitespace, any HTML or other markup is okay.</p>
<p>So we can see if our pointer is at the beginning of the file, if so, drop out of the process.</p>
<pre class="prettyprint">$tokens = $phpcsFile-&gt;getTokens();
if (T_OPEN_TAG === $tokens[$stackPtr]['code'])
{
	if (0 === $stackPtr)
	{
		return;
	}
}</pre>
<p>The getTokens() command returns all of the tokens for the current file in an associative array. (in case you didn&#8217;t realise).</p>
<p>The rest should be self explanatory.</p>
<p>We can also do a similar check for a PHP close tag</p>
<pre class="prettyprint">if (T_CLOSE_TAG === $tokens[$stackPtr]['code'])
{
	$content = $tokens[$stackPtr]['content'];
	if (
	    false === isset($tokens[($stackPtr + 1)]) &amp;&amp;
	    trim($content) === $content
	   )
	{
		return;
	}
}</pre>
<p><a title="Class file which returns when no whitespace is found." rel="shadowbox" href="http://github.com/b3cft/kingkludge-codesniffer/raw/7944b8cd7146d10a64b5bec55632e6c4a50c93cf/KingKludge/Sniffs/PHP/NoExtraneousWhiteSpace.php">View the basic standard file on GitHub</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kingkludge.net/2009/08/codesniffer-part-5-writing-an-examples-codesniffer-sniff/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CodeSniffer Part 4: How does CodeSniffer Work</title>
		<link>http://www.kingkludge.net/2009/02/codesniffer-part-4-how-does-codesniffer-work/</link>
		<comments>http://www.kingkludge.net/2009/02/codesniffer-part-4-how-does-codesniffer-work/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 16:03:08 +0000</pubDate>
		<dc:creator>Bob</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[code analysis]]></category>
		<category><![CDATA[codesniffer]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[static code analysis]]></category>

		<guid isPermaLink="false">http://www.kingkludge.net/2009/02/codesniffer-part-4-how-does-codesniffer-work/</guid>
		<description><![CDATA[Looking at the internal workings of CodeSniffer and how it does it's analysis. <a href="http://www.kingkludge.net/2009/02/codesniffer-part-4-how-does-codesniffer-work/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a title="Go back and read the previous article" href="/2009/02/codesniffer-part-3-writing-an-example-codesniffer-standard/">In the previous article</a> we looked at writing our own CodeSniffer standard based on pre-existing rules or sniffs.</p>
<p>This article will try to cover in-depth how CodeSniffer actually works to give insight into the next proposed article, writing a sniff from scratch.</p>
<h3>The PHP Tokenizer</h3>
<p>CodeSniffer works by extending the PHP tokenizer function.</p>
<p>Given the following section of code:</p>
<pre class="prettyprint">&lt;?php

function DoSomething(array $foo) {
    print_r($foo);
}

?&gt;&nbsp;&nbsp; </pre>
<p>and running it through PHP&#8217;s native tokenizer we get the following output</p>
<p><a title="PHP Tokenized version of foo.php" href="http://github.com/b3cft/kingkludge-codesniffer/raw/8e0348253cf01c27bb6966a79dae6b7a7e592323/misc/php_tokenized_foo.txt" rel="shadowbox">PHP Tokenized version of foo.php</a></p>
</p>
<pre></pre>
<p>PHP&#8217;s tokenizer only identifies a limited subset of PHP syntax <a title="List of PHP Tokens on the english PHP Manual site" href="http://www.php.net/manual/en/tokens.php" rel="shadowbox">as listed here</a>.</p>
<p>All other potential tokens get either identifies as a string, signified by the sub array[0] integer value of 307 or the constant <code>T_STRING</code>, else it simply returns the string value of the token i.e. those seen array values 17,18 and 20 in the sample output above.</p>
<p>To map the above integer values to PHP&#8217;s string constant name you can use the PHP function token_name() </p>
<p>For example:</p>
<pre class="commandline">$ php -r "print(token_name(369));"
T_CLOSE_TAG</pre>
<p>As once the PHP tokenizer has run, we have a lot of code still encapsulated as T_STRING or with no tokenizing done, CodeSniffer takes these simple tokens and expands them further. </p>
<p>CodeSniffer introduces new constants such as <code>T_TRUE</code>, <code>T_FALSE</code>, <code>T_NULL</code>, <code>T_PARENT</code>, <code>T_OPEN_CURLY_BRACKET</code> and so on.</p>
<p>This gives CodeSniffer considerable scope to be able to handle much finer detail of the PHP syntax. </p>
<h3>The PHP CodeSniffer Tokenizer</h3>
<p>When CodeSniffer first loads, the standard in use is determined from the command line or from the stored config. The standard is then loaded and all of that standard&#8217;s sniffs are loaded.</p>
<p>Each of the sniffs gets called via the register() method and a hash of all the tokens and classes is created.</p>
<p>Then CodeSniffer starts looking for the files to check, if a directory is specified, CodeSniffer iterates through the directories until a file with the correct extension is found, then each file is processed in turn.</p>
<p>If a list of files or a single file is specified, then the above step is skipped and CodeSniffer starts parsing the file(s) as defined in the parameters.</p>
<p>Once CodeSniffer has tokenized the file under analysis into one (rather large) multidimensional array of language syntax tokens, the rest is quite simple.</p>
<p>CodeSniffer breaks each file under examination down and does a series of context checks before processing the tokens and calling all the registered sniffs.</p>
<p>These checks are:</p>
<ol>
<li>Bracket Map: checking braces
</li>
<li>Scope Map: checking for class, function and conditional statement scopes
</li>
<li>Level Map: checking for class, function and conditional statement levels </li>
</ol>
<p><a title="PHP CodeSniffer Tokenized version of foo.php" href="http://github.com/b3cft/kingkludge-codesniffer/raw/698c0bb0dbb0441f4f759c96be697c37876aca31/misc/phpcs_tokenized_foo.txt" rel="shadowbox">If we look at the CodeSniffer Tokenized version of foo.php</a> we can see the levels of our sample script above.</p>
<p>Each Sniff in the standard has registered which tokens they are interested in being invoked to handle during the initialisation phase.</p>
<p>CodeSniffer then runs through each token in the file from beginning to end and calls all of the sniff process() method for sniffs that registered and interest in that token.</p>
<p>Finally all of the errors and warnings generated by those sniffs are organised into the desired report type and displayed.</p>
<p>So now we have an insight into how CodeSniffer works, in the next and final post in this series on CodeSniffer, we&#8217;ll look and writing a new Sniff.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kingkludge.net/2009/02/codesniffer-part-4-how-does-codesniffer-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CodeSniffer Part 3: Writing an example CodeSniffer Standard</title>
		<link>http://www.kingkludge.net/2009/02/codesniffer-part-3-writing-an-example-codesniffer-standard/</link>
		<comments>http://www.kingkludge.net/2009/02/codesniffer-part-3-writing-an-example-codesniffer-standard/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 17:06:04 +0000</pubDate>
		<dc:creator>Bob</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[code analysis]]></category>
		<category><![CDATA[codesniffer]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[static code analysis]]></category>

		<guid isPermaLink="false">http://www.kingkludge.net/2009/02/codesniffer-part-3-writing-an-example-codesniffer-standard/</guid>
		<description><![CDATA[Take a look at writing a custom CodeSniffer standard, by using rules (or Sniffs) from existing standards. <a href="http://www.kingkludge.net/2009/02/codesniffer-part-3-writing-an-example-codesniffer-standard/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="/2009/02/codesniffer-part-2-codesniffer-output/">Last time</a> we looked at some sample CodeSniffer reports and in the <strong>source</strong> report we saw that the <strong>Zend</strong> standard was also reporting errors from other standards.</p>
<pre class="commandline">$ phpcs --report=source --standard=Zend ./_rr

PHP CODE SNIFFER VIOLATION SOURCE SUMMARY
--------------------------------------------------------------------------------
STANDARD    CATEGORY            SNIFF                                      COUNT
--------------------------------------------------------------------------------
Zend        Files               Line length                                92
Generic     White space         Disallow tab indent                        65
Zend        Naming conventions  Valid variable name                        59
PEAR        White space         Scope closing brace                        33
PEAR        Functions           Function call signature                    26
PEAR        Control structures  Control signature                          12
PEAR        Files               Line endings                               11
PEAR        Functions           Function call argument spacing             5
Generic     PHP                 Disallow short open tag                    1
Zend        Files               Closing tag                                1
--------------------------------------------------------------------------------
A TOTAL OF 305 SNIFF VIOLATION(S) WERE FOUND IN 10 SOURCE(S)
--------------------------------------------------------------------------------</pre>
<p>Each CodeSniffer standard is comprised of rules or <strong>sniffs</strong>. A standard can contain a sniff from other standards.</p>
<p>This allows us to quickly and easily create our own custom standard by leveraging those rules that are already contained in existing standards.</p>
<p>To find out what we have available to use, we can looking for all the files that end in Sniff.php within the Standards folder. We can see we have 167 sniff available to use already (with version 1.2.0a1 anyway).</p>
<h3>Full list of available Sniffs</h3>
<pre class="commandline">cd {your pear path}/PHP/CodeSniffer/Standards
$ find ./ -name "*Sniff.php" -and -not -name "Abstract*"</pre>
<p><a title="Full List of CodeSniffer Sniffs available in version 1.2.0a1" href="https://raw.github.com/b3cft/kingkludge-codesniffer/ac3d2ac1713f1b112c10872ce1b3d3bdb208919f/misc/defaultCodeSnifferSniffs.txt" rel="shadowbox" target="_blank">Clicking here to see the full list of available Sniffs.</a></p>
<p>Some of these Sniffs are self explanatory some are less so, and would need a cursory glance at the code to see what they are checking  for.</p>
<p>Luckily most of the classes are well documented (as the PHPCS standard dictates!) so looking at the class phpdoc comment usually tells what the sniff is looking for.</p>
<p>Something to note is that you will find some of the sniffs are mutually exclusive:</p>
<p>e.g.</p>
<pre class="commandline">./Generic/Sniffs/Formatting/NoSpaceAfterCastSniff.php
./Generic/Sniffs/Formatting/SpaceAfterCastSniff.php
./Generic/Sniffs/Functions/OpeningFunctionBraceBsdAllmanSniff.php
./Generic/Sniffs/Functions/OpeningFunctionBraceKernighanRitchieSniff.php</pre>
<h3>Writing the standard</h3>
<p>So to start with we need to come up with a name for the standard.</p>
<p>So for this example I&#8217;m going to use KingKludge.</p>
<p>Now I prefer to develop in my home dir, but to get this sniff recognised you will need to have the standard available in {your pear path}/PHP/CodeSniffer/Standards/.</p>
<p>So I symlink my standard into the pear path, but you could work directly in the pear folder.</p>
<pre class="commandline">$ mkdir KingKludge
$ ln -s KingKludge {your pear path}/PHP/CodeSniffer/Standards/KingKludge</pre>
<p>Then we need to create the standard file. Which follows the naming convention {standard}CodingStandard.php so we end up with the following file.</p>
<p><a title="Bare CodeSniffer coding standard PHP class file on github" href="http://github.com/b3cft/kingkludge-codesniffer/raw/c27f50760e26d9db6cd685f9f0036360facbe501/KingKludge/KingKludgeCodingStandard.php" rel="shadowbox" target="_blank">KingKludgeCodingStandard.php</a></p>
<p>The underscores in the class name are important as the autoload function splits the path at underscores, so if you miss-type one of the path parts you will get a fatal error when the class attempts to load.</p>
<p>Assuming that you did have your class in the correct folder you can do run.</p>
<pre class="commandline">$ phpcs -i</pre>
<p>And you should see your new standard is listed as available for use.</p>
<p>As a timesaving tip, to stop us from having to type the standard name every time you can run CodeSniffer run the following command.</p>
<pre class="commandline">$ phpcs --config-set default_standard KingKludge</pre>
<p>Now unless we override with the <code>--standard</code> switch CodeSniffer will default to using the KingKludge standard.</p>
<h3>Adding some rules</h3>
<p>So now we have a new standard but it doesn&#8217;t do anything yet, as it has no rules to apply.</p>
<p>We have two methods in the class to define the rules or sniffs <code>getIncludedSniffs()</code> and <code>getExcludedSniffs()</code>. Not unsurprisingly these methods should return an array of the sniffs to include or exclude.</p>
<p>If we decided we wanted to make life easy for ourselves and base our standard on someone else&#8217;s standard, we can quite simply include all of their standard and then swap out the sniffs we don&#8217;t want for others we do.</p>
<p>For example, taking the <strong>Squiz</strong> coding standard.</p>
<pre class="prettyprint">public function getIncludedSniffs()
{
  return array(
    'Squiz',
  );
}</pre>
<p>Now say we want to swap the BSD style bracing rule for K&amp;R style braces, and we don&#8217;t want the CodeAnalyzer rule to run either.</p>
<p>So we add the K&amp;R braces Sniff to our include and add the CodeAnalyzer and BSD braces sniffs to the exclude.</p>
<pre class="prettyprint">public function getIncludedSniffs()
{
  return array(
    'Squiz',
    'Generic/Sniffs/Functions/OpeningFunctionBraceKernighanRitchieSniff.php',
  );
}

public function getExcludedSniffs()
{
  return array(
    'Generic/Sniffs/Functions/OpeningFunctionBraceBsdAllmanSniff.php',
    'Zend/Sniffs/Debug/CodeAnalyzerSniff.php',
  );
}</pre>
<p>That seems easy enough!</p>
<p>So now you can see how easily you can create your own standards by picking as few or as many sniffs as you want from existing standards.</p>
<p>Next time, understanding the internals of CodeSniffer and how it works.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kingkludge.net/2009/02/codesniffer-part-3-writing-an-example-codesniffer-standard/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CodeSniffer Part 2: CodeSniffer Output</title>
		<link>http://www.kingkludge.net/2009/02/codesniffer-part-2-codesniffer-output/</link>
		<comments>http://www.kingkludge.net/2009/02/codesniffer-part-2-codesniffer-output/#comments</comments>
		<pubDate>Sun, 01 Feb 2009 21:55:04 +0000</pubDate>
		<dc:creator>Bob</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[code analysis]]></category>
		<category><![CDATA[codesniffer]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[static code analysis]]></category>

		<guid isPermaLink="false">http://www.kingkludge.net/?p=62</guid>
		<description><![CDATA[I take a look and some of the standards and reports available in CodeSniffer by default. <a href="http://www.kingkludge.net/2009/02/codesniffer-part-2-codesniffer-output/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Continuing from <a href="/2009/01/codesniffer-part-1-introduction-to-codesniffer/">Part 1: Introduction to CodeSniffer</a> this time looking at and interpreting the output from CodeSniffer.</p>
<p>If we take an example block of code such as the following.</p>
<pre class="prettyprint"> 
&nbsp;
&lt;?php

function DoSomething(array $foo) {
    print_r($foo);
}

?&gt;
&nbsp;</pre>
<p>And run it through CodeSniffer with the <strong>Zend</strong> coding standard we get:</p>
<pre class="commandline">$ phpcs --standard=Zend foo.php

FILE: /home/bob/sample/foo.php
--------------------------------------------------------------------------------
FOUND 2 ERROR(S) AND 1 WARNING(S) AFFECTING 2 LINE(S)
--------------------------------------------------------------------------------
 2 | ERROR   | End of line character is invalid; expected "\n" but found "\r\n"
 4 | ERROR   | Opening brace should be on a new line
 4 | WARNING | Consider putting global function "DoSomething" in a static class
--------------------------------------------------------------------------------</pre>
<p>If we then run the same code through the <strong>PHPCS</strong> standard we get a more in-depth set of violations:</p>
<pre class="commandline">$ phpcs --standard=PHPCS foo.php

FILE: /home/bob/sample/foo.php
--------------------------------------------------------------------------------
FOUND 16 ERROR(S) AND 2 WARNING(S) AFFECTING 6 LINE(S)
--------------------------------------------------------------------------------
 2 | ERROR   | End of line character is invalid; expected "\n" but found "\r\n"
 2 | ERROR   | End of line character is invalid; expected "\n" but found "\r\n"
 2 | ERROR   | Additional whitespace found at start of file
 3 | ERROR   | Missing file doc comment
 4 | WARNING | Consider putting global function "DoSomething" in a static class
 4 | ERROR   | Missing function doc comment
 4 | ERROR   | Function name "DoSomething" is invalid; consider "doSomething"
   |         | instead
 4 | ERROR   | Expected "function abc(...)\n"; found "function abc(...) "
 4 | ERROR   | Function name "DoSomething" is not in camel caps format
 4 | ERROR   | Expected 2 blank lines before function; 1 found
 4 | ERROR   | Opening brace should be on a new line
 4 | ERROR   | Opening brace should be on a new line
 4 | ERROR   | Opening brace should be on a new line
 5 | WARNING | The use of function print_r() is discouraged
 6 | ERROR   | Expected //end DoSomething()
 6 | ERROR   | Expected 1 blank line before closing function brace; 0 found
 6 | ERROR   | Expected 2 blank lines after function; 1 found
 8 | ERROR   | Additional whitespace found at end of file
--------------------------------------------------------------------------------</pre>
<p>Hopefully you can see that the <strong>PHPCS</strong> standard is significantly more strict that the previous.</p>
<p>Also you should see that apart from more style based checks, this standard also checks for whitespace at the beginning and end of the file. Whitespace being echoed can be very important for some PHP frameworks. When lots of files are included as part of the execution, especially if they are dynamically loaded, the whitespace can cause a fatal error if header information is also being sent to the browser.</p>
<p>The other issues contained in this report are based around the project code layout and documentation requirements.</p>
<h3>Other reports</h3>
<p>With the release of CodeSniffer 1.2.x there are some new reporting types available.</p>
<p>Rather than the full in-depth report, two reports that I find quite useful for gauging a project&#8217;s status are the <strong>summary</strong> and <strong>source</strong> reports.</p>
<p><strong>Summary</strong> reports the number of errors and warnings found on a file by file basis over a directory tree.</p>
<pre class="commandline">$ phpcs --report=summary --standard=Zend ./_rr

PHP CODE SNIFFER REPORT SUMMARY
--------------------------------------------------------------------------------
FILE                                                            ERRORS  WARNINGS
--------------------------------------------------------------------------------
.../yocal/apps/frontend/modules/_rr/templates/_partial_rr1.php  23      3
...yocal/apps/frontend/modules/_rr/templates/_partial_rr10.php  4       1
...yocal/apps/frontend/modules/_rr/templates/_partial_rr11.php  7       4
.../yocal/apps/frontend/modules/_rr/templates/_partial_rr2.php  8       2
.../yocal/apps/frontend/modules/_rr/templates/_partial_rr3.php  18      2
.../yocal/apps/frontend/modules/_rr/templates/_partial_rr4.php  43      3
.../yocal/apps/frontend/modules/_rr/templates/_partial_rr5.php  22      4
.../yocal/apps/frontend/modules/_rr/templates/_partial_rr6.php  39      3
.../yocal/apps/frontend/modules/_rr/templates/_partial_rr7.php  24      1
.../yocal/apps/frontend/modules/_rr/templates/_partial_rr8.php  17      2
...yocal/apps/frontend/modules/_rr/templates/_thumbsUpDown.php  71      4
--------------------------------------------------------------------------------
A TOTAL OF 276 ERROR(S) AND 29 WARNING(S) WERE FOUND IN 11 FILE(S)
--------------------------------------------------------------------------------</pre>
<p><strong>Source</strong> shows the  type of errors and warnings found in a project:</p>
<pre class="commandline">$ phpcs --report=source --standard=Zend ./_rr

PHP CODE SNIFFER VIOLATION SOURCE SUMMARY
--------------------------------------------------------------------------------
STANDARD    CATEGORY            SNIFF                                      COUNT
--------------------------------------------------------------------------------
Zend        Files               Line length                                92
Generic     White space         Disallow tab indent                        65
Zend        Naming conventions  Valid variable name                        59
PEAR        White space         Scope closing brace                        33
PEAR        Functions           Function call signature                    26
PEAR        Control structures  Control signature                          12
PEAR        Files               Line endings                               11
PEAR        Functions           Function call argument spacing             5
Generic     PHP                 Disallow short open tag                    1
Zend        Files               Closing tag                                1
--------------------------------------------------------------------------------
A TOTAL OF 305 SNIFF VIOLATION(S) WERE FOUND IN 10 SOURCE(S)
--------------------------------------------------------------------------------</pre>
<p>As you can see from this report, although we are using the <strong>Zend</strong> standard, it consists of individual rules from multiple standards.</p>
<p>In the next part of this series I will cover how to write your own standard, by selecting rules from existing standards.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kingkludge.net/2009/02/codesniffer-part-2-codesniffer-output/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>CodeSniffer Part 1: Introduction to CodeSniffer</title>
		<link>http://www.kingkludge.net/2009/01/codesniffer-part-1-introduction-to-codesniffer/</link>
		<comments>http://www.kingkludge.net/2009/01/codesniffer-part-1-introduction-to-codesniffer/#comments</comments>
		<pubDate>Sat, 31 Jan 2009 15:51:08 +0000</pubDate>
		<dc:creator>Bob</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[code analysis]]></category>
		<category><![CDATA[codesniffer]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[static code analysis]]></category>

		<guid isPermaLink="false">http://www.kingkludge.net/2009/01/codesniffer-part-1-introduction-to-codesniffer/</guid>
		<description><![CDATA[This is a rough transcript of a lightning talk I gave during a team meeting at Yahoo! completely off the cuff, but I am in the process of writing this up as a Yahoo! Tech Talk, and also, as this is not internally sensitive, like most of the stuff I've been working on for the last two years, I'll see if it can be release on Yahoo Developers Network. <a href="http://www.kingkludge.net/2009/01/codesniffer-part-1-introduction-to-codesniffer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This started as a quick blog post on my way home. I was drunk, and shouldn&#8217;t have been blogging. I&#8217;d been to the leaving do of two of my great colleagues at Yahoo!</p>
<p>It ended up way too long,&#160; so I have split it up into sections and will post as a series.</p>
<p>This is a rough transcript of a lightning talk I gave during a team meeting at Yahoo! completely off the cuff, but I am in the process of writing this up as a Yahoo! Tech Talk, and also, as this is not internally sensitive, like most of the stuff I&#8217;ve been working on for the last two years, I&#8217;ll see if it can be release on <a href="http://developer.yahoo.com">Yahoo Developers Network</a>.</p>
<h3>What is CodeSniffer?</h3>
<p>CodeSniffer is almost a <abbr title="Static Code Analysis"><a title="Static code analysis" href="http://en.wikipedia.org/wiki/Static_code_analysis">SCA</a></abbr> tool. It allows a set of rules or a <strong>Standard</strong> to be applied to source code.</p>
<p>These rules can be used to detect common programming errors or <a href="http://en.wikipedia.org/wiki/Anti-patterns">Anti Patterns</a>, it can also be used to define a set of Coding Standards&#160; for your project.</p>
<p>It is down to your project to come up with some Coding Standards or <a title="Zend Project Coding Standards" href="http://framework.zend.com/wiki/display/ZFDEV/PHP+Coding+Standard+(draft)">apply a pre-existing set of standards</a> for your team to adhere to.</p>
<p>CodeSniffer comes with a set of coding standards already defined that are regularly used by other teams.</p>
<p>These are:</p>
<ul>
<li>MySource </li>
<li>PEAR </li>
<li>PHPCS </li>
<li>Squiz </li>
<li>Zend </li>
</ul>
<p>Analysing your code using one or more of these standards will highlight how the code you have provided stacks up against the project&#8217;s coding standard.</p>
<h3>How to install CodeSniffer</h3>
<pre class="commandline">$ sudo pear install PHP_CodeSniffer</pre>
<p>This will download and install the CodeSniffer utility from the PEAR repository.</p>
<h3>How to run CodeSniffer</h3>
<p>Simply run:</p>
<pre class="commandline">$ phpcs --standard=&lt;standard&gt; &lt;path to file or directory&gt;</pre>
<p>You will be shown a list any errors or warnings in your code. </p>
<p>CodeSniffer will also exit with a non-zero status code. This can be useful if you are using a Makefile to test your code or some build tool like Phing, or if your CodeSniffer rules are being run as part of a Continuous Integration system.</p>
<p>In the next post I will run through some of the standards and reports.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kingkludge.net/2009/01/codesniffer-part-1-introduction-to-codesniffer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

