Hi! Thanks for contributing!
For the best experience for everyone, there's a few guidelines we'd like everyone to follow.
This is a work-in-progress, so feel free to put ideas forward as to coding styles. The current guideline is based on suggestions from team members, and the recommendations from the PHP Framework Interop Group
- Files are UTF-8 encoded without a BOM (PSR-1)
- Only use long-syntax php tags:
<?php
and omit the closing tag at the end of a file. (PSR-1) - PHP 5.5 please, nothing newer as it won't run in production.
- Files contain a single class definition, and the file is named for the class. Alternatively, they should contain a script, not both. (PSR-1)
Namespacing currently isn't implemented, but we should be looking towards this goal.
-
A single tab per level of indentation please.
-
Opening braces go on the next line for methods and classes, but on the same line for control structures (PSR-1).
-
Spaces before and after brackets, not inside (PSR-1).
Quick example:
class Foo extends FooBase implements IFoo
{
public function sampleFunction($a, $b = null)
{
if ($a === $b) {
bar();
} elseif ($a > $b) {
$foo->bar($arg1);
} else {
BazClass::bar($arg2, $arg3);
}
}
final public static function bar()
{
// method body
}
}
Soft limit of 80 chars, hard limit of 120 please. Lines longer than 130 chars make code review on GitHub nasty.
UpperCamelCase
for classes. (PSR-1)lowerCamelCase
for methods. (PSR-1)UPPER_CASE
for constants. (PSR-1)- Properties should have names which closely match their backing fields:
<?php
class Foo
{
private $foo;
public function getFoo()
{
return $this->foo;
}
public function setFoo($foo)
{
$this->foo = $foo;
}
}
- Interfaces should be called ISomething.
- The ternary (
?:
) operator should only be used where appropriate - short expressions only please! - Heredoc/Nowdoc should not be used for output - use templates. Extended SQL statements are OK.
Some how-tos for some of the technologies and libraries we use.
We use PDO for database access, backed by MySQL 5.5 compatible databases.
Table names in our database are lowercase singular forms (request
, user
, ban
) of the data they store. PK is always a surrogate integer key called id
generated by the auto_increment
attribute.
Accessing the database is done either at an entity level through subclasses of DataObject
(preferred), or directly through PDO. The DataObject
class and it's subclasses implement the active record pattern.
Firstly, you'll need to grab a copy of the relevant database object:
$database = gGetDb();
This is a PDO(ish) object which you can do what you need to with.
You can grab entities using the static methods defined on them:
$database = gGetDb();
$request = Request::getById($id, $database);
All queries using data which is not 100% guaranteed to be safe and obviously safe (aka: hard-coded nearby) must be parameterised using prepare()
. Don't sanitise the data yourself, pass it as a parameter.
$statement = $database->prepare("INSERT INTO geolocation (address, data) VALUES (:address, :data);");
$statement->bindValue(":address", $address);
$statement->bindValue(":data", $data);
$statement->execute();
Please use transactions for all new code. The easiest way to do this is to wrap your code in a transactionally()
call as a callback. The database class will then wrap your code in a try/catch block with automatic transaction commit/rollback. Throw a TransactionException
if you encounter an error and need to abort.
$database = gGetDb();
$database->transactionally(function() use ($database)
{
$database->exec(<<<SQL
UPDATE user
SET
oauthrequesttoken = null,
oauthrequestsecret = null,
oauthaccesstoken = null,
oauthaccesssecret = null,
oauthidentitycache = null;
SQL
);
});
We use Smarty as a templating engine to handle all output to the web.
Smarty is very powerful, and allows us to put display logic directly within the templates, leaving our PHP code free of display code to cleanly handle the business logic.
No display code should be in the PHP files, everything should be in the templates, and as everything is contained in the templates, escaping for display can be done exactly at the point of display, and it's obvious where data isn't escaped for display. Therefore, no escaping should be done in the PHP code.
We use v3.1.14 of Smarty currently, and it's probably a better idea to get yourself familiar with it from their documentation. Useful sections: