Before diving into coding for Venddor IO, make sure to thoroughly review "PHP The Right Way." As Uncle Bob mentioned at O'Reilly Commons, adopt the Boy Scouts' principle: "Always leave the campground cleaner than you found it." If you encounter any code that isn't in line with the best practices and standards provided here, take the initiative to improve it, even if it's not your code.
$cart_content.Right: $counter, $user_id, $product, $is_valid
Wrong: $с, $uid, $obj, $flag
For variables holding a list of similar objects, use the _list suffix like $products_list.
Right:
foreach ($applied_promotion_list as $applied_promotion) {
// Code here is easy to distinguish
}
Wrong:
foreach ($applied_promotions as $applied_promotion) {
// This might be confusing
}
Boolean variables should start with prefixes such as is_, has_, or other suitable verbs.
Right: $is_valid, $has_rendered, $has_children, $use_cache
Wrong: $valid, $render_flag, $parentness_status, $cache
Avoid starting variable names with an underscore. Instances like $cache, $_cache, $__cache have been problematic in the past.
SORT_ORDER_ASC.Class[].Here's the example of formatting done right:
/**
* Generates date-time intervals of a given period for sales reports
*
* @param Timezone[] $timezone_list List of timezones to be used
* @param int $interval_id Sales reports interval ID
* @param int $timestamp_from Timestamp of report period beginning date
* @param int $timestamp_to Timestamp of report period end date
* @param int $limit Maximal number of the generated intervals.
* Also, this string is used to illustrate
* the wrapped and aligned long comment.
*
* @deprecated 4.4.1
* @return array
*/
Be cautious about using the Registry::get() method inside loops as it can impact performance.
Avoid excessive nesting or indentation in your code. If a function has more than 3 levels of indentation, consider refactoring.
Here are 2 examples:
<?php
function foobar($foo, $bar, $baz = null)
{
if (!empty($foo['foo_bar'])) {
$foo_bar = $foo['foo_bar'];
if (!empty($bar) && $foo_bar > 10) {
if (!empty($baz)) {
// No actions even take place until this point.
}
}
}
return false;
}
<php
public static function filterPickupPoints($data, $service_params)
{
$pickup_points = array();
if (!empty($service_params['deliveries'])) {
foreach ($data as $key => $delivery) {
if (!empty($delivery['is_pickup_point']) && in_array($key, $service_params['deliveries'])) {
foreach ($delivery['pickupPoints'] as $pickup) {
$pickup_points[$pickup['id']] = $pickup;
}
}
}
}
return $pickup_points;
}
PHP is a dynamically typed language, which means any declared variable can be assigned any data type. While this offers flexibility, it also introduces potential issues, which might result in unpredictable outcomes during code execution.
It's essential to understand the data type a variable should hold and structure your code accordingly. By doing so, you won't accidentally compare strings with integers or mix arrays with zeros.
By documenting the expected and returned data types using PHPDoc, you can provide clarity when you create a function or method. This ensures that you're always aware of the data type you're working with. Consequently, you can frequently employ the === strict comparison operator, making debugging easier for you and your peers.
In PHP 7, it's encouraged to use strict types for function return values and parameters.
You might often notice empty strings being used as default values. However, in PHP, there's a designated data type for that – null. Using 0 or an empty string can cause logical errors in your code. Therefore, always use null and the === operator for your conditions.
Avoid using conditions like !empty($_REQUEST), as they can be hard to read, especially when part of intricate expressions. Only use inverted conditions if the alternative would make the code even more unclear.
Function names should be in lowercase and start either with fn_, or with db_, like fn_get_module_option_variants.
When multiple arguments have default values or are secondary in importance, group them into a $params array. This streamlines the process by passing only the main arguments and the $params array.
If you find the same piece of code in multiple locations within a controller or function, it's a sign that it should be extracted into a separate function.
Avoid modifying the value of a passed variable by reference unless absolutely necessary. Instead, let the function return the modified value. This approach is more transparent and avoids unintended side-effects. Passing variables by reference also doesn't offer memory-saving benefits in PHP.
Ideally, a function should have just one exit point. Multiple exits are permissible if:
If a function becomes outdated, it's crucial to mark it as deprecated to prevent its unintentional use.
Follow CamelCase for naming classes, interfaces, and traits. Ensure that your classes, interfaces, and traits belong to the appropriate namespace. In Vendor IO, the base namespace is Tygh.
ABackend, ADatabaseConnection.ICountable, IFilesystemDriver.Correct: $a->getApiUrl(), $a = new Rest();, class ApiTest
Incorrect: $a->getAPIURL(), $a = new REST();, class APITest
The rules for naming constants within classes mirror those for external constants. Example:
class Api
{
const DEFAULT_REQUEST_FORMAT = 'text/plain';
}
All core and module-related entities in Venddor io should be under the Tygh namespace. If entities relate to a particular functionality, they should have a shared sub-namespace, like block management classes (Tygh\BlockManager).
Files utilizing classes, interfaces, or traits should have a use directive at the start to specify the utilized namespaces. If class names from varying namespaces collide, use aliasing to resolve conflicts.
Each entity, be it class, interface, or trait, should reside in its distinct file. Although developers often break this rule by declaring both a class and an exception in the same file, it's best avoided.
Modules should confine their classes, interfaces, and traits to their dedicated namespace, \Tygh\Addons\ModuleName.
The use directives should be grouped collectively for clarity.
Avoid crafting singleton classes and classes composed only of static methods. They pose challenges when writing unit tests.
Formulate your queries adhering to specific standards:
When encountering an error that hinders further program execution, Venddor io has exceptions to facilitate debugging.
To use an exception, summon it like this:
use Tygh\Exceptions\DeveloperException;
...