How do you keep your code readable?

  • WritingBadCode
  • Graduate
  • Graduate
  • User avatar
  • Posts: 214
  • Loc: Sweden

Post 3+ Months Ago

I was writing a site in PHP a few days ago this was the only thing I focused on and everything was so obvious, then JavaScript cough my interest and now when I go back to the code and find a little bug I realize that damn. I might as well rewrite a lot of this from scratch, at least some of the functions. This should eliminate bugs and make the code better looking. I never really thought I would be unable to properly understand my variables and functions. I thought that only happens to others.:mrgreen:What are the practices that people here follow to make their code understandable?

Personally I do the following: I try to give variables names that represent their functionality, and the same goes with any functions. =/ I usually add a one line comment when I write something that might be slightly hard to understand (but I didn't this time).
  • natas
  • PHP Ninja
  • Proficient
  • natas
  • Posts: 308
  • Loc: AFK

Post 3+ Months Ago

I have been working on modding a forum for a friend of mine who wants a lot of new stuff added that is impossible to find a cookie cutter for. So, I always add a comment where I add stuff and a short description as to what I did, so the next guy doesn't have to do so much guesswork.
  • spork
  • Brewmaster
  • Silver Member
  • User avatar
  • Posts: 6254
  • Loc: Seattle, WA

Post 3+ Months Ago

You should consider reading Code Complete by Steve McConnell. It's considered one of the best "best practices" books available.
  • WritingBadCode
  • Graduate
  • Graduate
  • User avatar
  • Posts: 214
  • Loc: Sweden

Post 3+ Months Ago

Thanks for the suggestions. I might look for that book as well in some days from now, when I got a lot of free time!
  • Bogey
  • Genius
  • Genius
  • Bogey
  • Posts: 8416
  • Loc: USA

Post 3+ Months Ago

Below is a sample of a function within a class.
PHP Code: [ Select ]
     /*
      * public function set_opts( array $options)
      *     @array $options - The array that we use to set the options to
      *         The key is the option name while the value is the value
      *             array('cache_results' => true);
      *
      * Function to set some options outside of the class
      */
   
    public function set_opts($options)
    {
        // Checking if we have a cache_results option
        if(isset($options['cache_results']))
        {
            // We do... set it to true or false...
            $this->cache_results = ($options['cache_results'] == true) ? true : false;
        }
    }
  1.      /*
  2.       * public function set_opts( array $options)
  3.       *     @array $options - The array that we use to set the options to
  4.       *         The key is the option name while the value is the value
  5.       *             array('cache_results' => true);
  6.       *
  7.       * Function to set some options outside of the class
  8.       */
  9.    
  10.     public function set_opts($options)
  11.     {
  12.         // Checking if we have a cache_results option
  13.         if(isset($options['cache_results']))
  14.         {
  15.             // We do... set it to true or false...
  16.             $this->cache_results = ($options['cache_results'] == true) ? true : false;
  17.         }
  18.     }

I keep the code indented by 4 spaces (not a tab... not sure why). I comment each and every line of code that I write to make sure that when I come back, I'll be able to understand the code and make it better. I describe the function and it's variable in a block comment before I write the function. I sometimes provide an example of how to use the function in the comment block I put before the function...
PHP Code: [ Select ]
    /*
     * public function build_key_query( array $sql)
     *      @array $sql - the SQL array
     *
     * Function that builds queries using an array
     * Usage example...
     *
     * $sql = array(
     *              'SELECT'    => '*',
     *              'FROM'      => '`database`.`table`',
     *              'JOIN'      => '`table2',
     *              'ON'        => '`table1`.`field1` = `table2`.`field2`',
     *              'WHERE'     => array(
     *                                  '`field1`' => 'value1',
     *                                  '`field2`' => 'value2'),
     *              'ORDER BY'  => '`field2`',
     *              'ASC'       => null
     * );
     */
  1.     /*
  2.      * public function build_key_query( array $sql)
  3.      *      @array $sql - the SQL array
  4.      *
  5.      * Function that builds queries using an array
  6.      * Usage example...
  7.      *
  8.      * $sql = array(
  9.      *              'SELECT'    => '*',
  10.      *              'FROM'      => '`database`.`table`',
  11.      *              'JOIN'      => '`table2',
  12.      *              'ON'        => '`table1`.`field1` = `table2`.`field2`',
  13.      *              'WHERE'     => array(
  14.      *                                  '`field1`' => 'value1',
  15.      *                                  '`field2`' => 'value2'),
  16.      *              'ORDER BY'  => '`field2`',
  17.      *              'ASC'       => null
  18.      * );
  19.      */

I name my variables with a name that best describes it's function in the least amount of words possible. The same goes to functions and class names...
At the very top of a class page or any PHP file, the first thing I do is write a comment block describing the page's purpose.
I comment on every variable I set to describe the functionality/the use of a variable.
PHP Code: [ Select ]
    // Variables used throughout the class for connection purposes
    private $var_file = 'includes/vars.xml';    // The location of database variables (Relative to the main PHP file using).
    private $persistant = false;                // If we need to use a persistant connection, set this to true
    private $free_result = true;                // Clears the resource result after every call
    private $admin_debug = true;                // If the debugging should be created for the admin... ONLY if for admin
    private $cache_results = true;              // If you want to use the caching capabilities, set this to true
    private $cache_dir = 'cache/sql/';          // The directory where the cache files would be written to
    private $silent = false;                    // Silence all errors (graceful error) if set to true
    private $log_errors = true;                 // Wether we should log the errors or not
    private $log_file = 'logs/sql.txt';         // The location of the log file
    private $cache_time_limit = 60;             // The amount of seconds you want the cache to exist (1 Day [86400] by default)
    // 60 = 1 Minute; 3600 = 1 Hour; 43200 = 12 Hours; 2629743.83 = 1 Month; 15778463 = 6 Months; 31556926 = 1 Year
  1.     // Variables used throughout the class for connection purposes
  2.     private $var_file = 'includes/vars.xml';    // The location of database variables (Relative to the main PHP file using).
  3.     private $persistant = false;                // If we need to use a persistant connection, set this to true
  4.     private $free_result = true;                // Clears the resource result after every call
  5.     private $admin_debug = true;                // If the debugging should be created for the admin... ONLY if for admin
  6.     private $cache_results = true;              // If you want to use the caching capabilities, set this to true
  7.     private $cache_dir = 'cache/sql/';          // The directory where the cache files would be written to
  8.     private $silent = false;                    // Silence all errors (graceful error) if set to true
  9.     private $log_errors = true;                 // Wether we should log the errors or not
  10.     private $log_file = 'logs/sql.txt';         // The location of the log file
  11.     private $cache_time_limit = 60;             // The amount of seconds you want the cache to exist (1 Day [86400] by default)
  12.     // 60 = 1 Minute; 3600 = 1 Hour; 43200 = 12 Hours; 2629743.83 = 1 Month; 15778463 = 6 Months; 31556926 = 1 Year

I keep every part of my code formatted into columns (As you can see above).
I keep arrays that overflow into the next line formatted with a hard break at the end of each line and the beginning indented to match with the start of the array's values.
PHP Code: [ Select ]
    // Allowed SQL query functions to be performed. For added security wall.
    private $sql_queries = array('SELECT', 'FROM', 'LEFT JOIN', 'JOIN', 'RIGHT JOIN', 'INNER JOIN', 'OUTER JOIN', 'OUTER RIGHT JOIN',
                                 'OUTER LEFT JOIN', 'INNER RIGHT JOIN', 'INNER LEFT JOIN', 'WHERE', 'ORDER BY', 'ASC', 'DESC', 'GROUP BY',
                                 'HAVING', 'ON', 'AVG', 'COUNT', 'SUM', 'FIRST', 'LAST', 'MAX', 'MIN', 'UCASE', 'LCASE', 'MID', 'LEN',
                                 'ROUND', 'NOW', 'FORMAT', 'ABS', 'SIGN', 'MOD', 'ROUND', 'POW', 'SQRT', 'LEAST', 'GREATEST', 'LOWER',
                                 'UPPER', 'CONCAT', 'LENGTH', 'LTRIM', 'TRIM', 'RTRIM', 'SUBSTRING', 'DATEOB', 'USER', 'PRIVGROUPS',
                                 'IF', 'COALESCE', 'UNIQUEKEY', 'TONUMBER', 'RAND', 'SELECT DISTINCT', 'UPDATE', 'DELETE', 'INSERT',
                                 'UNION', 'DELETE FROM');
  1.     // Allowed SQL query functions to be performed. For added security wall.
  2.     private $sql_queries = array('SELECT', 'FROM', 'LEFT JOIN', 'JOIN', 'RIGHT JOIN', 'INNER JOIN', 'OUTER JOIN', 'OUTER RIGHT JOIN',
  3.                                  'OUTER LEFT JOIN', 'INNER RIGHT JOIN', 'INNER LEFT JOIN', 'WHERE', 'ORDER BY', 'ASC', 'DESC', 'GROUP BY',
  4.                                  'HAVING', 'ON', 'AVG', 'COUNT', 'SUM', 'FIRST', 'LAST', 'MAX', 'MIN', 'UCASE', 'LCASE', 'MID', 'LEN',
  5.                                  'ROUND', 'NOW', 'FORMAT', 'ABS', 'SIGN', 'MOD', 'ROUND', 'POW', 'SQRT', 'LEAST', 'GREATEST', 'LOWER',
  6.                                  'UPPER', 'CONCAT', 'LENGTH', 'LTRIM', 'TRIM', 'RTRIM', 'SUBSTRING', 'DATEOB', 'USER', 'PRIVGROUPS',
  7.                                  'IF', 'COALESCE', 'UNIQUEKEY', 'TONUMBER', 'RAND', 'SELECT DISTINCT', 'UPDATE', 'DELETE', 'INSERT',
  8.                                  'UNION', 'DELETE FROM');

If it isn't an array full of values but an array that has keys and values then I set it up the following way: (Notice the columns)
PHP Code: [ Select ]
    // Allowed SQL functions (0 = Not Allowed; 1 = Allowed)
    private $all_funcs = array('CREATE'         => 0,
                               'DROP'           => 0,
                               'ALTER'          => 0,
                               'CREATE INDEX'   => 1,
                               'UPDATE'         => 1,
                               'INSERT'         => 1,
                               'SELECT'         => 1
                           );
  1.     // Allowed SQL functions (0 = Not Allowed; 1 = Allowed)
  2.     private $all_funcs = array('CREATE'         => 0,
  3.                                'DROP'           => 0,
  4.                                'ALTER'          => 0,
  5.                                'CREATE INDEX'   => 1,
  6.                                'UPDATE'         => 1,
  7.                                'INSERT'         => 1,
  8.                                'SELECT'         => 1
  9.                            );

I sometimes need to right an instructional comment or just an explanation on why I'm doing something the way I did...
PHP Code: [ Select ]
        /*
         * Overwriting silent to false if admin debug is set to true. This way, if the admin
         *  debug is set to true, the admin would be able to see all the errors thrown by the
         *  class and give a better idea of whats going on if something doesn't work.
         */
        if($this->admin_debug === true)
        {
            $this->silent = false;
        }
  1.         /*
  2.          * Overwriting silent to false if admin debug is set to true. This way, if the admin
  3.          *  debug is set to true, the admin would be able to see all the errors thrown by the
  4.          *  class and give a better idea of whats going on if something doesn't work.
  5.          */
  6.         if($this->admin_debug === true)
  7.         {
  8.             $this->silent = false;
  9.         }

That's about it from what I can think and from the time I'm given right now... I might come back later and improve on this post :)
  • WritingBadCode
  • Graduate
  • Graduate
  • User avatar
  • Posts: 214
  • Loc: Sweden

Post 3+ Months Ago

Good addition there Bogey!
  • this213
  • Guru
  • Guru
  • User avatar
  • Posts: 1260
  • Loc: ./

Post 3+ Months Ago

If I'm using anything that's abstracted 2 or more levels out, I make a note of where it's defined so the next guy doesn't have to dig through 8000 files to find it. Other than that, the only comments I make are either saying "doing this now" or, rarely, to explain particularly complex segments. I certainly don't comment on every single variable's purpose because, hopefully, whoever is digging around in my code will be able to read the code itself - and if they can't, I get paid twice as much to fix my own code that they break.

I am, however, a code-nazi. All of my code follows my own set of formatting guidelines which over the years has stabilized to the point that a routine from one project can slide into another project and look as though it were written for it. This includes code layout, naming conventions and file separation for the most part. Some specific examples include creating classes and functions in their own files, using identical bracketing and indentation, keeping comments to 1 line (unless it's the copyright) and I don't allow direct output from any functions unless the whole purpose of that function is output. I also make a comment at a closing bracket as to what's closing, and I always bracket conditionals. Those two alone can save a lot of time trying to debug someone else's code (or your own after a couple months of not looking at it).

Though I've never written down any of my own code guidelines, developers who work for me magically follow them with near perfection (sometimes I have to say something here and there, but it's rare and only with new people). Once they see how I have my code, they follow suit.
  • sherma
  • Silver Member
  • Silver Member
  • User avatar
  • Posts: 127

Post 3+ Months Ago

I don't know why, but this post reminds me of something I ran across while reading a few nights ago and that is "obfuscate code" .. do you know they actually have international contests for that?! :)

anyway, I agree with Bogey's way. My only problem is remembering to rewrite my comments when I go back and change something in the code.

Post Information

  • Total Posts in this topic: 8 posts
  • Users browsing this forum: No registered users and 67 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
cron
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.