|Access||Adobe photoshop||Algoritmi||Autocad||Baze de date||C||C sharp|
|Calculatoare||Corel draw||Dot net||Excel||Fox pro||Frontpage||Hardware|
|Php||Power point||Retele calculatoare||Sql||Tutorials||Webdesign||Windows|
The PHP Coding Standard is with
permission based on Todd Hoff's C++ Coding Standard.
Rewritten for PHP by Fredrik Kristiansen / DB Medialab, Oslo 2000-2001.
Using this Standard. If you want to make a local copy of this standard and use it as your own you are perfectly free to do so. That's why we made it! If you find any errors or make any improvements please email me (firstname.lastname@example.org) the changes so I can merge them in.
Please verify that you have
the most recent version of this document.
It helps if the standard annoys everyone in some way so everyone feels they are on the same playing field. The proposal here has evolved over many projects, many companies, and literally a total of many weeks spent arguing. It is no particular person's style and is certainly open to local amendments.
When a project tries to adhere to common standards a few good things happen:
programmers can go into any code and figure out what's going on
new people can get up to speed quickly
people new to PHP are spared the need to develop a personal style and defend it to the death
people new to PHP are spared making the same mistakes over and over again
people make fewer mistakes in consistent environments
programmers have a common enemy :-)
Now the bad:
the standard is usually stupid because it was made by someone who doesn't understand PHP
the standard is usually stupid because it's not what I do
standards reduce creativity
standards are unnecessary as long as people are consistent
standards enforce too much structure
people ignore standards anyway
The experience of many projects leads to the conclusion that using coding standards makes the project go smoother. Are standards necessary for success? Of course not. But they help, and we need all the help we can get! Be honest, most arguments against a particular standard come from the ego. Few decisions in a reasonable standard really can be said to be technically deficient, just matters of taste. So be flexible, control the ego a bit, and remember any project is fundamentally a team effort.
The use of the word 'shall' in this document requires that any project using this document must comply with the stated standard.
The use of the word 'should' directs projects in tailoring a project-specific standard, in that the project must include, exclude, or tailor the requirement, as appropriate.
The use of the word 'may' is similar to 'should', in that it designates optional requirements.
First, any serious concerns about the standard should be brought up and worked out within the group. Maybe the standard is not quite appropriate for your situation. It may have overlooked important issues or maybe someone in power vehemently disagrees with certain issues :-)
In any case, once finalized hopefully people will play the adult and understand that this standard is reasonable, and has been found reasonable by many other programmers, and therefore is worthy of being followed even with personal reservations.
Failing willing cooperation it can be made a requirement that this standard must be followed to pass a code inspection.
Failing that the only solution is a massive tickling party on the offending party.
Maybe it's possible, but it's weak and uninteresting.
It is true and I told you so.
I thought of it first.
How could it be otherwise.
If you come to objects with a negative preconception please keep an open mind. You may still conclude objects are bunk, but there's a road you must follow to accept something different. Allow yourself to travel it for a while.
Names are the heart of programming. In the past people believed knowing someone's true name gave them magical power over that person. If you can think up the true name for something, you give yourself and the people coming after power over the code. Don't laugh!
A name is the result of a long deep thought process about the ecology it lives in. Only a programmer who understands the system as a whole can create a name that 'fits' with the system. If the name is appropriate everything fits together naturally, relationships are clear, meaning is derivable, and reasoning from common human expectations works as expected.
If you find all your names could be Thing and DoIt then you should probably revisit your design.
Name the class after what it is. If you can't think of what it is that is a clue you have not thought through the design well enough.
Compound names of over three words are a clue your design may be confusing various entities in your system. Revisit your design. Try a CRC card session to see if your objects have more responsibilities than they should.
Avoid the temptation of bringing the name of the class a class derives from into the derived class's name. A class should stand on its own. It doesn't matter what it derives from.
Suffixes are sometimes helpful. For example, if your system uses agents then naming something DownloadAgent conveys real information.
Usually every method and function performs an action, so the name should make clear what it does: CheckForErrors() instead of ErrorCheck(), DumpDataToFile() instead of DataFile(). This will also make functions and data objects more distinguishable.
Suffixes are sometimes useful:
For example: RetryMax to mean the maximum number of retries, RetryCnt to mean the current retry count.
Prefixes are sometimes useful:
For example: IsHitRetryLimit.
Take for example NetworkABCKey. Notice how the C from ABC and K from key are confused. Some people don't mind this and others just hate it so you'll find different policies in different code so you never know what to call something.
John Johnson's complete data structure library could use JJ as a prefix, so classes would be:class JjLinkList
Array element names follow the same rules as a variable.
It's tradition for global constants to named this way. You must be careful to not conflict with other predefined globals.
Of the three major brace placement strategies two are acceptable, with the first one listed being preferable:
There are more reasons than psychological for preferring the first style. If you use an editor (such as vi) that supports brace matching, the first is a much better style. Why? Let's say you have a large block of code and want to know where the block ends. You move to the first brace hit a key and the editor finds the matching brace. Example:if ($very_long_condition && $second_very_long_condition)
To move from block to block you just need to use cursor down and your brace matching key. No need to move to the end of the line to match a brace then jerk back and forth.
Do not do any real work in an object's constructor. Inside a constructor initialize variables only and/or do only actions that can't fail.
Create an Open() method for an object which completes construction. Open() should be called after object instantiation.
Functions should not keep static variables that prevent a function from being reentrant.
It's up to the programmer. Different bracing styles will yield slightly different looks. One common approach is:if (condition) // Comment
If you have else if statements then it is usually a good idea to always have an else block for finding unhandled cases. Maybe put a log message in the else even if there is no corrective action taken.
Always put the constant on the left hand side of an equality/inequality comparison. For example:
if ( 6 == $errorNum )
One reason is that if you leave out one of the = signs, the pharser will find the error for you. A second reason is that it puts the value you are looking for right up front where you can find it instead of buried at the end of your expression. It takes a little time to get used to this format, but then it really gets useful.
Continue and break are really disguised gotos so they are covered here.
Continue and break like goto should be used sparingly as they are magic in code. With a simple spell the reader is beamed to god knows where for some usually undocumented reason.
The two main problems with continue are:
Consider the following example where both problems occur:while (TRUE)
Note: 'A lot of code' is necessary in order that the problem cannot be caught easily by the programmer.
From the above example, a further rule may be given: Mixing continue with break in the same loop is a sure way to disaster.
The trouble is people usually try and stuff too much code in between the ? and :. Here are a couple of clarity rules to follow:
There should be only one statement per line unless the statements are very closely related.
Always document a null body for a for or while statement so that it is clear that the null body is intentional and not missing code.
Do not default the test for non-zero, i.e.
is better than
even though FAIL may have the value 0 which PHP considers to be false. An explicit test will help you out later when somebody decides that a failure return should be -1 instead of 0. Explicit comparison should be used even if the comparison value will never change; e.g., if (!($bufsize % strlen($str))) should be written instead as if (0 == ($bufsize % strlen($str))) to reflect the numeric (not boolean) nature of the test. A frequent trouble spot is using strcmp to test for string equality, where the result should never ever be defaulted.
The non-zero test is often defaulted for predicates and other functions or expressions which meet the following restrictions:
Do not check a boolean value for equality with 1 (TRUE, YES, etc.); instead test for inequality with 0 (FALSE, NO, etc.). Most functions are guaranteed to return 0 if false, but only non-zero if true. Thus,
The ++ and -- operators count as assignment statements. So, for many purposes, do functions with side effects. Using embedded assignment statements to improve run-time performance is also possible. However, one should consider the tradeoff between increased speed and decreased maintainability that results when embedded assignments are used in artificial places. For example,
should not be replaced by
even though the latter may save one cycle. In the long run the time difference between the two will decrease as the optimizer gains maturity, while the difference in ease of maintenance will increase as the human memory of what's going on in the latter piece of code begins to fade.
Reuse across projects is almost impossible without a common framework in place. Objects conform to the services available to them. Different projects have different service environments making object reuse difficult.
Developing a common framework takes a lot of up front design effort. When this effort is not made, for whatever reasons, there are several techniques one can use to encourage reuse:
One common enemy of reuse is people not making libraries out of their code. A reusable class may be hiding in a program directory and will never have the thrill of being shared because the programmer won't factor the class or classes into a library.
One reason for this is because people don't like making small libraries. There's something about small libraries that doesn't feel right. Get over it. The computer doesn't care how many libraries you have.
If you have code that can be reused and can't be placed in an existing library then make a new library. Libraries don't stay small for long if people are really thinking about reuse.
If you are afraid of having to update makefiles when libraries are recomposed or added then don't include libraries in your makefiles, include the idea of services. Base level makefiles define services that are each composed of a set of libraries. Higher level makefiles specify the services they want. When the libraries for a service change only the lower level makefiles will have to change.
Most companies have no idea what code they have. And most programmers still don't communicate what they have done or ask for what currently exists. The solution is to keep a repository of what's available.
In an ideal world a programmer could go to a web page, browse or search a list of packaged libraries, taking what they need. If you can set up such a system where programmers voluntarily maintain such a system, great. If you have a librarian in charge of detecting reusability, even better.
Another approach is to automatically generate a repository from the source code. This is done by using common class, method, library, and subsystem headers that can double as man pages and repository entries.
Consider your comments a story describing the system. Expect your comments to be extracted by a robot and formed into a man page. Class comments are one part of the story, method signature comments are another part of the story, method arguments another part, and method implementation yet another part. All these parts should weave together and inform someone else at another point of time just exactly what you did and why.
Comments should document decisions. At every point where you had a choice of what to do place a comment describing which choice you made and why. Archeologists will find this the most useful information.
Use a document extraction system like ccdoc . Other sections in this document describe how to use ccdoc to document a class and method.
These headers are structured in such a way as they can be parsed and extracted. They are not useless like normal headers. So take time to fill them out. If you do it right once no more documentation may be necessary.
Each part of the project has a specific comment layout.
Explicitly comment variables changed out of the normal control flow or other code likely to break during maintenance. Embedded keywords are used to point out issues and potential problems. Consider a robot will parse your comments looking for keywords, stripping them out, and making a report so people can make a special effort where needed.
See Interface and Implementation Documentation for more details on how documentation should be laid out.
There are two main audiences for documentation:
With a little forethought we can extract both types of documentation directly from source code.
Class users need class interface information which when structured correctly can be extracted directly from a header file. When filling out the header comment blocks for a class, only include information needed by programmers who use the class. Don't delve into algorithm implementation details unless the details are needed by a user of the class. Consider comments in a header file a man page in waiting.
Class implementors require in-depth knowledge of how a class is implemented. This comment type is found in the source file(s) implementing a class. Don't worry about interface issues. Header comment blocks in a source file should cover algorithm issues and other design decisions. Comment blocks within a method's implementation should explain even more.
Every directory should have a README file that covers:
Consider a new person coming in 6 months after every original person on a project has gone. That lone scared explorer should be able to piece together a picture of the whole project by traversing a source directory tree and reading README files, Makefiles, and source file headers.
The Open/Closed principle states a class must be open and closed where:
The Open/Closed principle is a pitch for stability. A system is extended by adding new code not by changing already working code. Programmers often don't feel comfortable changing old code because it works! This principle just gives you an academic sounding justification for your fears :-)
In practice the Open/Closed principle simply means making good use of our old friends abstraction and polymorphism. Abstraction to factor out common processes and ideas. Inheritance to create an interface that must be adhered to by derived classes.
This section contains some guidelines for PHP/Apache configuration.
HTTP_*_VARS are either enabled or disabled. When enabled all variables must be accessed through $HTTP_*_VARS[key]. When disabled all variables can be accessed by the key name.
There is lots of different extension variants on PHP files (.html, .php, .php3, .php4, .phtml, .inc, .class).
When you choose to use the .html extension on all your web documents, you should put all your libraries in files with the extension .php. When compared with the c language, the .c becomes .html and .h becomes .php.
This section contains some miscellaneous do's and don'ts.
Does the programmer really mean assignment here? Often yes, but usually no. The solution is to just not do it, an inverse Nike philosophy. Instead use explicit tests and avoid assignment with an implicit test. The recommended form is to do the assignment before doing the test:
Sometimes large blocks of code need to be commented out for testing. The easiest way to do this is with an if (0) block:function example()
You can't use /**/ style comments because comments can't contain comments and surely a large block of your code will contain a comment, won't it?
There are two major idioms for creating accessors.
Get/Set is ugly. Get and Set are strewn throughout the code cluttering it up.
But one benefit is when used with messages the set method can transparently transform from native machine representations to network byte order.
Attributes as Objects is clean from a name perspective. When possible use this approach to attribute access.
Layering is the primary technique for reducing complexity in a system. A system should be divided into layers. Layers should communicate between adjacent layers using well defined interfaces. When a layer uses a non-adjacent layer then a layering violation has occurred.
A layering violation simply means we have dependency between layers that is not controlled by a well defined interface. When one of the layers changes code could break. We don't want code to break so we want layers to work only with other adjacent layers.
Sometimes we need to jump layers for performance reasons. This is fine, but we should know we are doing it and document appropriately.
If you can make a formal code review work then my hat is off to you. Code reviews can be very useful. Unfortunately they often degrade into nit picking sessions and endless arguments about silly things. They also tend to take a lot of people's time for a questionable payback.
My god he's questioning code reviews, he's not an engineer!
Not really, it's the form of code reviews and how they fit into normally late chaotic projects is what is being questioned.
First, code reviews are way too late to do much of anything useful. What needs reviewing are requirements and design. This is where you will get more bang for the buck.
Get all relevant people in a room. Lock them in. Go over the class design and requirements until the former is good and the latter is being met. Having all the relevant people in the room makes this process a deep fruitful one as questions can be immediately answered and issues immediately explored. Usually only a couple of such meetings are necessary.
If the above process is done well coding will take care of itself. If you find problems in the code review the best you can usually do is a rewrite after someone has sunk a ton of time and effort into making the code 'work.'
You will still want to do a code review, just do it offline. Have a couple people you trust read the code in question and simply make comments to the programmer. Then the programmer and reviewers can discuss issues and work them out. Email and quick pointed discussions work well. This approach meets the goals and doesn't take the time of 6 people to do it.
A common build system and source code control system should be put in place as early as possible in a project's lifecycle, preferably before anyone starts coding. Source code control is the structural glue binding a project together. If programmers can't easily use each other's products then you'll never be able to make a good reproducible build and people will piss away a lot of time. It's also hell converting rogue build environments to a standard system. But it seems the right of passage for every project to build their own custom environment that never quite works right.
Some issues to keep in mind:
Make a web page or document or whatever. New programmers shouldn't have to go around begging for build secrets from the old timers.
If you have the money many projects have found Clear Case a good system. Perfectly workable systems have been build on top of GNU make and CVS. CVS is a freeware build environment built on top of RCS. Its main difference from RCS is that is supports a shared file model to building software.
The earlier people get used to using a bug tracking system the better. If you are 3/4 through a project and then install a bug tracking system it won't be used. You need to install a bug tracking system early so people will use it.
Programmers generally resist bug tracking, yet when used correctly it can really help a project:
Not sexy things, just good solid project improvements.
Source code control should be linked to the bug tracking system. During the part of a project where source is frozen before a release only check-ins accompanied by a valid bug ID should be accepted. And when code is changed to fix a bug the bug ID should be included in the check-in comments.
I recommend Mantis for bug tracking. It is released under the general public license.
Responsibility for software modules is scoped. Modules are either the responsibility of a particular person or are common. Honor this division of responsibility. Don't go changing things that aren't your responsibility to change. Only mistakes and hard feelings will result.
Face it, if you don't own a piece of code you can't possibly be in a position to change it. There's too much context. Assumptions seemingly reasonable to you may be totally wrong. If you need a change simply ask the responsible person to change it. Or ask them if it is OK to make such-n-such a change. If they say OK then go ahead, otherwise holster your editor.
Every rule has exceptions. If it's 3 in the morning and you need to make a change to make a deliverable then you have to do it. If someone is on vacation and no one has been assigned their module then you have to do it. If you make changes in other people's code try and use the same style they have adopted.
Programmers need to mark with comments code that is particularly sensitive to change. If code in one area requires changes to code in an another area then say so. If changing data formats will cause conflicts with persistent stores or remote message sending then say so. If you are trying to minimize memory usage or achieve some other end then say so. Not everyone is as brilliant as you.
The worst sin is to flit through the system changing bits of code to match your coding style. If someone isn't coding to the standards then ask them or ask your manager to ask them to code to the standards. Use common courtesy.
Code with common responsibility should be treated with care. Resist making radical changes as the conflicts will be hard to resolve. Put comments in the file on how the file should be extended so everyone will follow the same rules. Try and use a common structure in all common files so people don't have to guess on where to find things and how to make changes. Check-in changes as soon as possible so conflicts don't build up.
As an aside, module responsibilities must also be assigned for bug tracking purposes.
PHP Tags are used for delimit PHP from html in a file. There are several ways to do this. <?php ?>, <? ?>, <script language='php'> </script>, <% %>, and <?=$name?>. Some of these may be turned off in your PHP settings.
A magic number is a bare-naked number used in source code. It's magic because no-one has a clue what it means including the author inside 3 months. For example:if (22 == $foo)
In the above example what do 22 and 19 mean? If there was a number change or the numbers were just plain wrong how would you know?
Heavy use of magic numbers marks a programmer as an amateur more than anything else. Such a programmer has never worked in a team environment or has had to maintain code or they would never do such a thing.
Instead of magic numbers use a real name that means something. You should use define(). For example:define('PRESIDENT_WENT_CRAZY', '22');
Now isn't that better?
How many methods should an object have? The right answer of course is just the right amount, we'll call this the Goldilocks level. But what is the Goldilocks level? It doesn't exist. You need to make the right judgment for your situation, which is really what programmers are for :-)
The two extremes are thin classes versus thick classes. Thin classes are minimalist classes. Thin classes have as few methods as possible. The expectation is users will derive their own class from the thin class adding any needed methods.
While thin classes may seem 'clean' they really aren't. You can't do much with a thin class. Its main purpose is setting up a type. Since thin classes have so little functionality many programmers in a project will create derived classes with everyone adding basically the same methods. This leads to code duplication and maintenance problems which is part of the reason we use objects in the first place. The obvious solution is to push methods up to the base class. Push enough methods up to the base class and you get thick classes.
Thick classes have a lot of methods. If you can think of it a thick class will have it. Why is this a problem? It may not be. If the methods are directly related to the class then there's no real problem with the class containing them. The problem is people get lazy and start adding methods to a class that are related to the class in some willow wispy way, but would be better factored out into another class. Judgment comes into play again.
Thick classes have other problems. As classes get larger they may become harder to understand. They also become harder to debug as interactions become less predictable. And when a method is changed that you don't use or care about your code will still have to be retested, and re-released.
Note: The PEAR Coding Standards apply to code that is part of the official PEAR distribution (that is, either distributed with PHP or available for download from the PHP PEAR repository).
Use an indent of 4 spaces, with no tabs. If you use Emacs to edit PEAR code, you should set indent-tabs-mode to nil. Here is an example mode hook that will set up Emacs according to these guidelines (you will need to ensure that it is called when you are editing PHP files):
|(defun php-mode-hook ()
(setq tab-width 4
(and (string-match '/(PEAR|pear)/' (buffer-file-name))
(string-match '.php$' (buffer-file-name))))))
Here are vim rules for the same thing:
These include if, for, while, switch, etc. Here is an example if statement, since it is the most complicated of them:
Control statements should have one space between the control keyword and opening parenthesis, to distinguish them from function calls.
You are strongly encouraged to always use curly braces even in situations where they are technically optional. Having them increases readability and decreases the likelihood of logic errors being introduced when new lines are added.
For switch statements:
Functions should be called with no spaces between the function name, the opening parenthesis, and the first parameter; spaces between commas and each parameter, and no space between the last parameter, the closing parenthesis, and the semicolon. Here's an example:
As displayed above, there should be one space on either side of an equals sign used to assign the return value of a function to a variable. In the case of a block of related assignments, more space may be inserted to promote readability:
Function declarations follow the 'one true brace' convention:
Arguments with default values go at the end of the argument list. Always attempt to return a meaningful value from a function if one is appropriate. Here is a slightly longer example:
Inline documentation for classes should follow the PHPDoc convention, similar to Javadoc. More information about PHPDoc can be found here: https://www.phpdoc.de/
Non-documentation comments are strongly encouraged. A general rule of thumb is that if you look at a section of code and think 'Wow, I don't want to try and describe that', you need to comment it before you forget how it works.
C style comments (/* */) and standard C++ comments (//) are both fine. Use of Perl/shell style comments (#) is discouraged.
Anywhere you are unconditionally including a class file, use require_once(). Anywhere you are conditionally including a class file (for example, factory methods), use include_once(). Either of these will ensure that class files are included only once. They share the same file list, so you don't need to worry about mixing them - a file included with require_once() will not be included again by include_once().
Note: include_once() and require_once() are statements, not functions. You don't need parentheses around the filename to be included.
Always use <?php ?> to delimit PHP code, not the <? ?> shorthand. This is required for PEAR compliance and is also the most portable way to include PHP code on differing operating systems and setups.
All source code files in the core PEAR distribution should contain the following comment block as the header:
This section applies only to packages using CVS at cvs.php.net.
Include the $Id$ CVS keyword in each file. As each file is edited, add this tag if it's not yet present (or replace existing forms such as 'Last Modified:', etc.).
The rest of this section assumes that you have basic knowledge about CVS tags and branches.
CVS tags are used to label which revisions of the files in your package belong to a given release. Below is a list of the required and suggested CVS tags:
(required) Used for tagging a release. If you don't use it, there's no way to go back and retrieve your package from the CVS server in the state it was in at the time of the release.
(branch, optional) If you feel you need to roll out a release candidate before releasing, it's a good idea to make a branch for it so you can isolate the release and apply only those critical fixes before the actual release. Meanwhile, normal development may continue on the main trunk.
(branch, optional) If you need to make 'micro-releases' (for example 1.2.1 and so on after 1.2), you can use a branch for that too, if your main trunk is very active and you want only minor changes between your micro-releases.
Only the RELEASE tag is required, the rest are recommended for your convenience.
Below is an example of how to tag the 1.2 release of the 'Money_Fast' package:
|$ cd pear/Money_Fast
$ cvs tag RELEASE_1_2
By doing this you make it possible for the PEAR web site to take you through the rest of your release process.
Here's an example of how to create a QA branch:
|$ cvs tag QA_2_0_BP
$ cvs rtag -b -r QA_2_0_BP QA_2_0
$ cvs update -r QA_2_0
$ cvs tag RELEASE_2_0RC1
and then the actual release, from the same branch:
$ cvs tag RELEASE_2_0
The 'QA_2_0_BP' tag is a 'branch point' tag, which is the start point of the tag. It's always a good idea to start a CVS branch from such branch points. MAINT branches may use the RELEASE tag as their branch point.
Use 'example.com' for all example URLs, per RFC 2606.
Classes should be given descriptive names. Avoid using abbreviations where possible. Class names should always begin with an uppercase letter. The PEAR class hierarchy is also reflected in the class name, each level of the hierarchy separated with a single underscore. Examples of good class names are:
Functions and methods should be named using the 'studly caps' style (also referred to as 'bumpy case' or 'camel caps'). Functions should in addition have the package name as a prefix, to avoid name collisions between packages. The initial letter of the name (after the prefix) is lowercase, and each letter that starts a new 'word' is capitalized. Some examples:
Private class members (meaning class members that are intended to be used only from within the same class in which they are declared; PHP does not yet support truly-enforceable private namespaces) are preceded by a single underscore. For example:
Constants should always be all-uppercase, with underscores to separate words. Prefix constant names with the uppercased name of the class/package they are used in. For example, the constants used by the DB:: package all begin with 'DB_'.
If your package needs to define global variables, their name should start with a single underscore followed by the package name and another underscore. For example, the PEAR package uses a global variable called $_PEAR_destructor_object_list.
Class 6, 7, 8, 19, 21, 29
Comment 14, 20, 21, 24
Function 6, 11
Global 10, 11
If 1, 6, 12, 13, 14, 15, 16, 17, 19, 20, 23, 25, 26, 27, 28, 29
Keywords 13, 20
Method 6, 8, 9
Source 26, 27
Politica de confidentialitate
Adauga cod HTML in site