webForumDet fria alternativet

Verktyg för att skriva bättre kod (PHP)

Webbutveckling

0 svar · 4 244 visningar · startad av SPiN

Medlem sedan mars 20007 896 inlägg
Frågan#1

När man skriver lite större applikationer är det bra om man följer vissa kodningsstandarder för att få lättläst kod (utöver att den ska vara lätt att hantera). Det märker man speciellt om man arbetar i en grupp, men även om man utvecklar en applikation själv så bör man hålla sig till dessa standarder - om projektet i framtiden ska omarbetas av någon annan. I det här inlägget tänkte jag nämna två verktyg som hjälper till med dokumentation av kod och som hjälper en till mer lättläst kod - det är återigen paket från PEAR, närmare bestämt PhpDocumentor samt PHP_CodeSniffer.

PhpDocumentor är ett paket som automatiskt genererar en dokumentation för en applikation, utifrån kommentarer i källkoden. PHP_CodeSniffer å sin sida är ett verktyg för att skriva mer lättläst kod, samtidigt som den ser över semantiken i koden. T.ex. ett booleanskt värde för falskt ska skrivas: false - inte FALSE, även om PHP-tolken godtar det. PhpDocumentor och PHP_CodeSniffer gör sig väldigt bra tillsammans, men man kan självklart använda paketen för sig om man vill det.

Både PhpDocumentor och PHP_CodeSniffer finns med i PEAR så de är lätta att installera:

$ pear install phpdocumentor
$ pear install php_codesniffer

Har man installerat PEAR så fungerar kommandot i både Windows och på GNU/Linux - annars finns paketen att ladda ned på PEAR's paketsida.
PhpDocumentor
PHP_CodeSniffer

Samtidigt som man skriver sin kod, lägger man in kommentarer för klasser, metoder och variabler som beskriver vad de gör och vad de beror på. Ett exempel för beskrivning av en klass:

/**
 * User entity class
 *
 * The {@link UserManager} class uses this class for user verification
 *
 * This class holds information about a user
 *
 * @category EntityClasses
 * @package  MyProject
 * @author   SPiN af webForum <spin@webforum.nu>
 * @license  http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link     http://www.myprojectswebpage.com
 * @todo     Extend the class with databas connectivity
 */
class User
{
...
    /**
     * Returns the current mode of this user.
     *
     * @access public
     * @return int The mode of the current user
     */
    public function getMode()
    {
        return $this->usermode;
    }
...

Som ni ser märker man ut med nycklar (börjar med @-tecken) vad som är specifikt för klassen eller metoden, samt en kortare beskrivning i början av kommentaren. Det finns väldigt mycket nycklar och sätt att skriva kommentarer, och det är långt ifrån nödvändigt att lära sig alla. Är det något speciellt man vill åt finns ju dokumentationen på nätet.

Själva PHP-dokumentet behöver en liknande beskrivning, med licenstext, upphovsman, paket, osv. tillsammans med för vilka PHP-versioner som paketet kan användas under och en paketbeskrivning. Under tiden man skriver sin kod och sina kommentarer kan man använda PHP_CodeSniffer för att se om det är något som behöver rättas till. Öppna en terminal och gå in i katalogen för ditt PHP-dokument och kör det genom PHP_CodeSniffer med kommandot 'phpcs':

$ phpcs MyProjectFile.php

Det finns olika växlar man kan ge till PHP_CodeSniffer och man kan till och med skapa egna filter för det - om man inte vill att Perl-kommentarer ska vara giltiga t.ex. kan man skriva ett filter för det. PHP_CodeSniffer kan nu spotta ur sig både felmeddelanden (fel intendering bl.a.) och varningar (för långa rader t.ex.). Får man ingen utskrift från PHP_CodeSniffer betraktas dokumentet som välformulerat.

När man är klar med projektet, och man har testat sin kod samt tänkt på prestanda är det dags att låta PhpDocumentor sköta sitt. Jag visar här två exempelfiler som båda passerar obemärkt genom PHP_CodeSniffer samt genererar en fin dokumentation.
User.php

<?php
/**
 * User entity class
 *
 * MyProjectName :: MyProject description
 *
 * PHP versions 3, 4 and 5
 *
 * Copyright (c) 2008 SPiN af webForum
 *
 * @category MainClasses
 * @package  MyProject
 * @author   SPiN af webForum <spin@webforum.nu>
 * @license  http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link     http://www.myprojectswebpage.com
 */
/**
 * User entity class
 *
 * The {@link UserManager} class uses this class for user verification
 *
 * This class holds information about a user
 *
 * @category MainClasses
 * @package  MyProject
 * @author   SPiN af webForum <spin@webforum.nu>
 * @license  http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link     http://www.myprojectswebpage.com
 * @todo     Extend the class with databas connectivity
 */
class User
{
    /**#@+
     * @access private
     */
    /**
     * This variable holds the username of the current user
     * @see setUsername(), getUsername()
     * @var string
     */
    private $_username;
    /**
     * This variable holds the mode of the current user
     * @see getMode(), setMode()
     * @var int
     */
    private $_usermode;
    /**#@-*/
    /**#@+
     * @access public
     */
    /**
     * This constant declares the mode to be active
     * @see setMode(), getMode()
     * @var int
     */
    public static final $ACTIVE = 1001;
    /**
     * This constant declares the mode to be inactive
     * @see setMode(), getMode()
     * @var int
     */
    public static final $INACTIVE = 1000;
    /**#@-*/
    /**
     * Set the name of the current user
     *
     * @param string $newName The name to be set
     *
     * @access public
     * @return void
     * @uses $_username
     */
    public function setUsername($newName)
    {
        $this->_username = $newName;
    }
    /**
     * Return the name of the current user
     *
     * @access public
     * @return string The current users name
     * @uses $_username
     */
    public function getUsername()
    {
        return $this->_username;
    }
    /**
     * Sets the mode of this user to either active or inactive,
     * using the class constants for identification
     *
     * @param int $mode The mode of the user, User::$ACTIVE or User::$INACTIVE
     *
     * @access public
     * @return void
     * @throws Exception
     */
    public function setMode($mode) 
    {
        if ($mode == self::$ACTIVE) {
            $this->_usermode = self::$ACTIVE;
            return;
        }
        if ($mode == self::$INACTIVE) {
            $this->_usermode = self::$INACTIVE;
            return;
        }
        $message = "setMode()-wrong parameter, User::\$ACTIVE or User::\$INACTIVE.";
        throw new Exception($message);
    }
    /**
     * Returns the current mode of this user.
     *
     * @access public
     * @return int The mode of the current user
     */
    public function getMode()
    {
        return $this->_usermode;
    }
}

UserManager.php

<?php
/**
 * Main class
 *
 * MyProjectName :: MyProject description
 *
 * PHP versions 3, 4 and 5
 *
 * Copyright (c) 2008 SPiN af webForum
 *
 * @category MainClasses
 * @package  MyProject
 * @author   SPiN af webForum <spin@webforum.nu>
 * @license  http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link     http://www.myprojectswebpage.com
 */
require_once "User.php";

/**
 * Main class
 *
 * Class used for creation of {@link User} instance
 *
 * This class creates a user.
 *
 * @category MainClasses
 * @package  MyProject
 * @author   SPiN af webForum <spin@webforum.nu>
 * @license  http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @link     http://www.myprojectswebpage.com
 */
class UserManager
{
    /**
     * This method returns an instance of the {@link User} class
     *
     * @access public
     * @return User An instance of a User
     */
    public function createUser()
    {
        $user = new User();
        $user->setUsername("SPiN");
        $user->setMode(User::$ACTIVE);
        return $user;
    }
}

Det minsta som behövs för att PhpDocumentor ska skapa en dokumentation är in-filer samt en mål-mapp. In-filerna (de PHP-dokument som ska dokumenteras) läggs till efter växeln -f (files), och mål-mappen anges efter växeln -t (target) - PhpDocumentor körs med kommandot 'phpdoc':

$ mkdir MyDocumentation
$ phpdoc -f UserManager.php,User.php -t ./MyDocumentation

Det tar inte många sekunder för PhpDocumentor att skapa dokumentation, som hamnar i prydliga .html-filer i mappen MyDocumentation. Den skapar även en sorterad TODO-lista för de filer man har angivit @todo-nyckeln.

Jag ska lägga till att jag inte följer PHP_CodeSniffer slaviskt, då jag tycker om att använda tabbar som indentering (PHP_CodeSniffer skriker till och hävdar att det ska vara minst 4 mellanslag istället) och jag tycker om att ha måsvingar som avslutare på rader för klasser och metoder (PHP_CodeSniffer tycker att måsvingar hör hemma på egna rader). Men det är en bra början till en snyggare kod! PhpDocumentor har jag inte använt så frekvent, men börjar komma igång med det eftersom att det är så urbota tråkigt att skriva dokumentation i efterhand.

Koda fint! Och med vänliga,

258 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
125 ms — deklarationer (db)
0 ms — hämta statistik (cache)
128 ms — hämta tråd, inlägg och bilagor (db)
117 ms — ändringar (db)