views:

10419

answers:

10

I recently started these naming conventions..

all functions & variables = camelCase

constants with define() = ALL_CAPS_AND_UNDERSCORES

Now I see a lot of other people mix up camelCase and underscores and they seem to have some sort of convention to it... What do you use and what is best? I've heard that public and private functions should have underscores before some.. I assume private have 2 underscores as in __construct() ?

Thank you!

+5  A: 

The methods with two underscores at the start are usually what's called "magic" methods. This includes __toString(), __call(), __get(), and __set(). There are more, but as far as naming conventions go, all you need to know is don't use a double underscore for your own method names. The double underscore was added to avoid conflicts with user functions, so adding your own defeats the purpose. :)

Constants are generally all in caps with underscores between. Sometimes they're prefixed with a common library name or something to show which constants are related to each other. for example: ENT_QUOTES, ENT_NO_QUOTES

Variables and function names should be lowerCamelCase, whereas class names should be UpperCamelCase.

Another convention is to start private variables and functions with a (single) underscore. This doesn't do anything special, though some frameworks (who still need PHP4 compatibility) treat these members as private implicitly. Given PHP5 has the private keyword, using an underscore before your private variables/functions is optional.

nickf
+5  A: 
class TestThing
{
    public $objectProperty;

    public function methodName() {
    }
}

function function_name( $argument = null ) {
}

$variable_name = 'hi'; //Non-object
$TestThing = new TestThing; //Object
orlandu63
+11  A: 

I recommend you to see some well known PHP projects, and review their naming conventions and coding standards, then you will be able to judge which conventions you will be able to follow.

Here are a few good examples:

And remember most important thing is being consistent in your naming conventions and coding style.

CMS
Excellent answer; however, the updated "official" naming conventions are here: http://news.php.net/php.standards/2
analytik
+2  A: 

The double underscore methods mentioned by nickf are called 'magic methods'. A full list can be found at http://uk3.php.net/oop5.magic

Rob Young
A: 

The standards you choose can vary a lot due to the language used. For example, in php all variables start with a $, so there's no need for a separate style to differentiate them. Thus you can do something like $name = new name(). I personally like this convention.

camelCase is an interesting idea but I just find it too ugly to use. I've adjusted my preferences several times over 20 years of programming, including dabbling in hungarian notation (talk about ugly!). Now I favor the following simple system:

$var_name FuncName() ClassName CONST_NAME

I also use an underscore prefix to indicate anything extraordinary about the item in question.

I think it's important not to be a nazi about the rules either, and remember the purpose of all this is readability and ease of use. I break these rules in limited cases for convenience. For example I have a heavily used, core class named "sys". I chose all lower case since because it is referenced so often.

+7  A: 

Personally, I use "unix_hacker" style for everything except for classes.

$instance = new Class()
$var_name = 5;
$x = get_x();

I used to use camel-case, but I switched so that my code would look more 'native' with PHP's built-in functions.

Logan Serman
I've seen native functions in PHP like this: `some_function`, `somefunction` and `someFunction`
alex
PHP functions are case insensitive, so `somefunction` and `someFunction` are equivalent. As far as I know, php.net documentation lists all functions in lowercase.
Zurahn
@Zurahn There are a lot of PHP5 stuff that is [camel case](http://www.php.net/manual/en/class.arrayaccess.php). (and their classes use Pascal Case).
alex
+1  A: 

I found this link for a PHP Coding Standard that doesn't look too bad: http://www.dagbladet.no/development/phpcodingstandard/

RFelix
+1  A: 

Drupal also has its own coding standards.

Wim Leers
This is my favorite.
Infinity
Except that "two spaces instead of one sensible tab" thing. And the fact that Drupal is nowhere near using real objects or namespaces.
analytik
Tabs never make sense to use when you're also using patches. And you should use patches.
Wim Leers
A: 

Quiet old thread but I'll give my comment if someone else finds this through searchmachines like me.

I prefer a slightly different convention than Adam:

$var_name funcName() ClassName CONST_NAME

The difference to Adam: I start function names lower case.

Basically I don't like lower case, underscored variable names. But there is a major drawback about camelCased variable names in PHP: Variable names in PHP are case sensitive and don't need to be declared. So a simple typo like $foobar instead of $fooBar can drive you crazy when debugging. There's no compiler who tells you that $foobar isn't initialized. There are IDEs like Zend Studio who shout out a warning if you read a variable which is maybe not initialized, but what if you can't use Zend Studio for some reason on a file or a single script? Typos like the foobar-example happen quite often if you type fast and don't hit the shift key long enough. Simply use lower case variable names makes them difficult to read if they are long. So i think lowercase, underscored variable names are the best choice in PHP.

Chris
A: 

I just wanted to throw my $0.02USD in here as well...

I've used many coding standards and systems over the years. I've recently jettisoned my Hungarian notation naming from my PHP projects. It was tough, but I like the results.

So, here's my thing.

Class names that are not part of an immediate project (i.e. library-ish stuff), start with "C". Example: CMyClass or CNewComponent.

Variable names that are NOT arguments, begin with "$_" to denote their locality.

Member names all begin with the same "$_" signature.

All variable and member names are descriptive and camel-cased.

All class members are PROTECTED by default and getter/setter methods are added as needed.

All non-public class members, static or otherwise, begin with an underscore.

I always use tabs, 4 characters wide.

Use PHPDOC on every method in your classes.

Here's a snippet:

<?php
/*
 * This file is part of the psYiiExtensions package.
 *
 * @copyright Copyright &copy; 2009 Pogostick, LLC
 * @link http://www.pogostick.com Pogostick, LLC.
 * @license http://www.pogostick.com/licensing
 */

/**
 * Provides a base class for code lookup tables in your database
 *
 * @package     psYiiExtensions
 * @subpackage  models
 *
 * @author      Jerry Ablan <[email protected]>
 * @version     SVN: $Id: CPSCodeTableModel.php 402 2010-09-11 23:00:16Z [email protected] $
 * @since       v1.0.6
 *
 * @filesource
 */
class CPSCodeTableModel extends CPSModel
{
    //********************************************************************************
    //* Constants
    //********************************************************************************

    /***
    * The name of our code table DDL
    */
    const DDL_NAME = 'code_t.sql';
    const DDL_TABLE_NAME = 'code_t';
    const DDL_DATA_NAME = 'code_install_data.sql';

    //********************************************************************************
    //* Private Members
    //********************************************************************************

    /**
     * @var integer A value filter
     */
    protected $_valueFilter = null;
    public function getValueFilter() { return $this->_valueFilter; }
    public function setValueFilter( $value ) { $this->_valueFilter = $value; }

    /**
     * @var string The column name for our "active" attribute.
     */
    protected $_activeAttributeName = 'active_ind';

    /**
     * @var string The class name of our "code" model
     */
    protected $_modelClass = 'Codes';

    //********************************************************************************
    //* Public Methods
    //********************************************************************************

    public function init()
    {
        parent::init();

        //  Get our model class
        $this->_modelClass = self::_findModelClass();
    }

    /**
    * Installs a standard code table into the database.
    *
    * @param CDbConnection $dbConnection Defaults to PS::_a()->db
    * @param string $name The code table name. Defaults to 'code_t'
    * @returns boolean
    */
    public static function install( $dbConnection = null, $name = self::DDL_TABLE_NAME )
    {
        $_db = PS::nvl( $dbConnection, PS::_db() );

        if ( $name && $_db )
        {
            $_path = Yii::getPathOfAlias( 'pogostick.templates.ddl' );

            $_sql = file_get_contents( $_path . self::DDL_NAME );
            if ( strlen( $_sql ) )
            {
                $_sql = str_ireplace( '%%TABLE_NAME', $name, $_sql );
                $_command = $_db->createCommand( $_sql );
                if ( $_command->execute() )
                {
                    $_sql = file_get_contents( $_path . self::DDL_DATA_NAME );

                    //  Load some codes...
                    if ( strlen( $_sql ) )
                    {
                        $_sql = str_ireplace( '%%TABLE_NAME', $name, $_sql );
                        $_command = $_db->createCommand( $_sql );
                        $_command->execute();
                    }
                }

                return true;
            }
        }

        return false;
    }

    /**
    * Get code rows
    * @param int $codeId Specific code ID to retrieve
    * @param string $codeType Retrieves all codes that are of this type
    * @param string $codeAbbreviation Retrieves all codes that are of this abbreviation. If type specicifed, further filters return set
    * @param string $sortOrder Optional sort order of result set. Defaults to PK (i.e. id)
    * @return array|string Depending on the parameters supplied, either returns a code row, an array of code rows, or a string.
    */
    protected static function getCodes( $codeId = null, $codeType = null, $codeAbbreviation = null, $sortOrder = null, $activeCodesOnly = true, $valueFilter = null )
    {
        $_criteria = null;
        $_modelClass = self::_findModelClass();
        $_model = call_user_func( array( $_modelClass, 'model' ) );

        if ( null === $sortOrder ) $sortOrder = $_model->primaryKey;

        //  Get a single code...
        if ( null !== $codeId ) return $_model->valueFilter( $valueFilter )->active( $activeCodesOnly )->findByPk( $codeId );

        $_condition = array();
        $_params = array();

        //  Get a specific code by type/abbr
        if ( null !== $codeType )
        {
            $_condition[] = 'code_type_text = :code_type_text';
            $_params[':code_type_text'] = $codeType;
        }

        if ( null !== $codeAbbreviation )
        {
            $_condition[] = 'code_abbr_text = :code_abbr_text';
            $_params[':code_abbr_text'] = $codeAbbreviation;
        }

        //  No conditions? Bail...
        if ( empty( $_condition ) )
            return null;

        $_criteria = array(
            'condition' => implode( ' AND ', $_condition ),
            'params' => $_params,
            'order' => PS::nvl( $sortOrder ),
        );

        return $_model->valueFilter( $valueFilter )->active( $activeCodesOnly )->findAll( $_criteria );
    }

    /**
    * @return array validation rules for model attributes.
    */
    public function rules()
    {
        return array(
            array( 'code_type_text', 'length', 'max' => 60 ),
            array( 'code_abbr_text', 'length', 'max' => 60 ),
            array( 'code_desc_text', 'length', 'max' => 255 ),
            array( 'assoc_text', 'length', 'max' => 255 ),
            array( 'id, active_ind, code_type_text, code_abbr_text, code_desc_text, create_date, lmod_date', 'required' ),
            array( 'id, active_ind, parnt_code_id', 'numerical', 'integerOnly' => true ),
            array( 'assoc_value_nbr', 'numerical' ),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'Id',
            'code_type_text' => 'Type',
            'code_abbr_text' => 'Abbreviation',
            'code_desc_text' => 'Description',
            'parnt_code_id' => 'Parent Code Id',
            'assoc_value_nbr' => 'Associated Number',
            'assoc_text' => 'Associated Text',
            'active_ind' => 'Active',
            'create_date' => 'Created On',
            'lmod_date' => 'Modified On',
        );
    }

    //********************************************************************************
    //* Statics
    //********************************************************************************

    /**
    * Returns the static model of the specified AR class.
    * @return CActiveRecord the static model class
    */
    public static function model( $sClassName = __CLASS__ )
    {
        return parent::model( $sClassName );
    }

    /**
    * Find a code by type
    *
    * @param string $codeType
    * @return array
    * @static
    */
    public static function findAllByType( $codeType, $sortOrder = 'code_desc_text', $valueFilter = null )
    {
        return self::getCodes( null, $codeType, null, $sortOrder, true, $valueFilter );
    }

    /**
    * Find a code by type
    *
    * @param string $codeType
    * @return array
    * @static
    */
    public static function findAllByAbbreviation( $codeAbbreviation, $codeType = null, $sortOrder = 'code_desc_text' )
    {
        return self::getCodes( null, $codeType, $codeAbbreviation, $sortOrder );
    }

    /**
    * Finds a single code by code_id
    *
    * Duplicates findByPk, but wanted to be consistent.
    *
    * @param integer $iCodeId
    * @return CActiveRecord
    * @static
    */
    public static function findById( $iCodeId )
    {
        return self::getCodes( $iCodeId );
    }

    /**
    * Retrieves the associated value for a code
    *
    * @param int $codeId
    * @return double
    */
    public function valueFilter( $value = null )
    {
        //  Nothing? Move along...
        if ( null === $value )
            return $this;

        //  Not an array? Make one...
        if ( ! is_array( $value ) ) $value = array( $value );

        //  No items?
        if ( empty( $value ) )
            return $this;

        //  Make string...
        if ( count( $value ) == 1 )
            $_condition = '( assoc_value_nbr is null or assoc_value_nbr = ' . $value[0] . ')';
        else
            $_condition = '( assoc_value_nbr is null or assoc_value_nbr in (' . implode( ',', $value ) . '))';

        $this->getDbCriteria()->mergeWith( array( 'condition' => $_condition ) );
        return $this;
    }

    /**
    * Returns a code's description
    *
    * @param int $codeId
    * @return string
    */
    public static function getCodeDescription( $codeId )
    {
        $_code = self::getCodes( $codeId );
        return $_code ? $_code->code_desc_text : null;
    }

    /**
    * Returns a code's abbreviation
    *
    * @param int $codeId
    * @return string
    */
    public static function getCodeAbbreviation( $codeId )
    {
        $_code = self::getCodes( $codeId );
        return $_code ? $_code->code_abbr_text : null;
    }

    /**
    * Returns a code's id given a type and abbreviation
    *
    * @param string $codeType
    * @param string $codeAbbreviation
    * @return integer
    */
    public static function getCodeFromAbbreviation( $codeType, $codeAbbreviation )
    {
        $_codeList = self::getCodes( null, $codeType, $codeAbbreviation );
        return ! empty( $_codeList )  ? $_codeList[0]->id : null;
    }

    /**
    * Retrieves the associated text for a code
    *
    * @param int $codeId
    * @return string
    */
    public static function getAssociatedText( $codeId )
    {
        $_code = self::getCodes( $codeId );
        return $_code ? $_code->assoc_text : null;
    }

    /**
    * Retrieves the associated value for a code
    *
    * @param int $codeId
    * @return double
    */
    public static function getAssociatedValue( $codeId )
    {
        $_code = self::getCodes( $codeId );
        return $_code ? $_code->assoc_value_nbr : null;
    }

    /**
    * Returns all rows based on type/abbr given
    * If it's a specific request, (i.e. type & abbr given) a single row is returned.
    *
    * @param string $codeType
    * @param string $codeAbbreviation
    * @return int|CPSCodeTableModel|array
    */
    public static function lookup( $codeType, $codeAbbreviation = null, $returnIdOnly = true )
    {
        $_code = self::getCodes( null, $codeType, $codeAbbreviation );
        return $_code ? ( $returnIdOnly ? $_code->id : $_code ) : null;
    }

    /**
     * Only return active code records as designated by the active_ind
     * @returns CPSCodeTableModel
     */
    public function active( $activeOnly = true )
    {
        if ( $activeOnly && $this->hasAttribute( $this->_activeAttributeName ) ) $this->getDbCriteria()->mergeWith( array( 'condition' => 'active_ind = :active_ind', 'params' => array( ':active_ind' => 1 ) ) );
        return $this;
    }

    /**
     * Finds and sets the model class for this object.
     * If your model class is not "Codes" and you're not running PHP 5.3.x+, override
     * this method to provide your own model name.
     * 
     * @return string The name of the model class
     */
    protected static function _findModelClass()
    {
        $_modelClass = 'Codes';

        //  Can't really use get_called_class with 5.2...
        if ( version_compare( PHP_VERSION, '5.3.0' ) >= 0 )
            $_modelClass = get_called_class();

        return $_modelClass;
    }
}
The Keeper of the Cheese