bg_image
header

Duplicate Code

Duplicate Code refers to instances where identical or very similar code appears multiple times in a program. It is considered a bad practice because it can lead to issues with maintainability, readability, and error-proneness.

Types of Duplicate Code

1. Exact Duplicates: Code that is completely identical. This often happens when developers copy and paste the same code in different locations.

Example:

def calculate_area_circle(radius):
    return 3.14 * radius * radius

def calculate_area_sphere(radius):
    return 3.14 * radius * radius  # Identical code

2. Structural Duplicates: Code that is not exactly the same but has similar structure and functionality, with minor differences such as variable names.

Example:

def calculate_area_circle(radius):
    return 3.14 * radius * radius

def calculate_area_square(side):
    return side * side  # Similar structure

3. Logical Duplicates: Code that performs the same task but is written differently.

Example:

def calculate_area_circle(radius):
    return 3.14 * radius ** 2

def calculate_area_circle_alt(radius):
    return 3.14 * radius * radius  # Same logic, different style

Disadvantages of Duplicate Code

  1. Maintenance Issues: Changes in one location require updating all duplicates, increasing the risk of errors.
  2. Increased Code Size: More code leads to higher complexity and longer development time.
  3. Inconsistency Risks: If duplicates are not updated consistently, it can lead to unexpected bugs.

How to Avoid Duplicate Code

1. Refactoring: Extract similar or identical code into a shared function or method.

Example:

def calculate_area(shape, dimension):
    if shape == 'circle':
        return 3.14 * dimension * dimension
    elif shape == 'square':
        return dimension * dimension

2. Modularization: Use functions and classes to reduce repetition.

3. Apply the DRY Principle: "Don't Repeat Yourself" – avoid duplicating information or logic in your code.

4. Use Tools: Tools like SonarQube or CodeClimate can automatically detect duplicate code.

Reducing duplicate code improves code quality, simplifies maintenance, and minimizes the risk of bugs in the software.


PSR-12

PSR-12 is a coding style guideline defined by the PHP-FIG (PHP Framework Interoperability Group). It builds on PSR-1 (Basic Coding Standard) and PSR-2 (Coding Style Guide), extending them to include modern practices and requirements.


Purpose of PSR-12

PSR-12 aims to establish a consistent and readable code style for PHP projects, facilitating collaboration between developers and maintaining a uniform codebase.


Key Guidelines of PSR-12

1. Indentation

  • Use 4 spaces for indentation (no tabs).

2. Line Length

  • Maximum line length should not exceed 120 characters.
  • Code may be broken into multiple lines for better readability.

3. Namespace and Use Statements

  • Add one blank line after the namespace declaration.
  • use statements should follow the namespace declaration.
  • Imported classes, functions, and constants should be alphabetically sorted without blank lines between them.
namespace App\Controller;

use App\Service\MyService;
use Psr\Log\LoggerInterface;
use Psr\Log\LoggerInterface;

4. Classes

  • The opening { for a class or method must be placed on the next line.
  • Visibility (public, protected, private) is mandatory for all methods and properties.
class MyClass
{
    private string $property;

    public function myMethod(): void
    {
        // code
    }
}

5. Methods and Functions

  • Each parameter must be placed on a new line if the parameter list is wrapped.
  • Return types should be explicitly declared.
public function myFunction(
    int $param1,
    string $param2
): string {
    return 'example';
}

6. Control Structures (if, while, for, etc.)

  • The opening { must be on the same line as the control structure.
  • A space is required between the control structure and the condition.
if ($condition) {
    // code
} elseif ($otherCondition) {
    // code
} else {
    // code
}

7. Arrays

  • Use the short syntax ([]) for arrays.
  • In multiline arrays, each element should appear on a new line.
$array = [
    'first' => 'value1',
    'second' => 'value2',
];

8. Type Declarations

  • Parameter, return, and property types are mandatory (where possible).
  • Nullable types are prefixed with ?.
public function getValue(?int $id): ?string
{
    return $id !== null ? (string) $id : null;
}

9. Files

  • PHP files must start with the <?php tag and must not include a closing ?> tag.
  • Add blank lines between declarations like classes or functions.

Differences from PSR-2

PSR-12 extends PSR-2 by:

  • Supporting modern PHP features (e.g., nullable types, declare(strict_types=1), traits, type hinting).
  • Clarifying rules for line lengths, wrapped method parameters, and arrays.
  • Requiring explicit type declarations.

Benefits of PSR-12

  • Simplifies code reviews.
  • Improves readability and maintainability.
  • Enhances interoperability between PHP projects.
  • Ensures consistency with modern PHP practices.

Summary

PSR-12 is the standard for modern and consistent PHP code. It improves code quality and simplifies collaboration, especially in team environments. Tools like PHP_CodeSniffer or PHP-CS-Fixer can help ensure adherence to PSR-12 effortlessly.


PSR-11

PSR-11 is a PHP Standard Recommendation (PHP Standard Recommendation) that defines a Container Interface for dependency injection. It establishes a standard way to interact with dependency injection containers in PHP projects.

Purpose of PSR-11

PSR-11 was introduced to ensure interoperability between different frameworks, libraries, and tools that use dependency injection containers. By adhering to this standard, developers can switch or integrate various containers without modifying their code.

Core Components of PSR-11

PSR-11 specifies two main interfaces:

  1. ContainerInterface
    This is the central interface providing methods to retrieve and check services in the container.

namespace Psr\Container;

interface ContainerInterface {
    public function get(string $id);
    public function has(string $id): bool;
}
    • get(string $id): Returns the instance (or service) registered in the container under the specified ID.
    • has(string $id): Checks whether the container has a service registered with the given ID.
  • 2. NotFoundExceptionInterface
    This is thrown when a requested service is not found in the container.

namespace Psr\Container;

interface NotFoundExceptionInterface extends ContainerExceptionInterface {
}

3. ContainerExceptionInterface
A base exception for any general errors related to the container.

Benefits of PSR-11

  • Interoperability: Enables various frameworks and libraries to use the same container.
  • Standardization: Provides a consistent API for accessing containers.
  • Extensibility: Allows developers to create their own containers that comply with PSR-11.

Typical Use Cases

PSR-11 is widely used in frameworks like Symfony, Laravel, and Zend Framework (now Laminas), which provide dependency injection containers. Libraries like PHP-DI or Pimple also support PSR-11.

Example

Here’s a basic example of using PSR-11:

use Psr\Container\ContainerInterface;

class MyService {
    public function __construct(private string $message) {}
    public function greet(): string {
        return $this->message;
    }
}

$container = new SomePSR11CompliantContainer();
$container->set('greeting_service', function() {
    return new MyService('Hello, PSR-11!');
});

if ($container->has('greeting_service')) {
    $service = $container->get('greeting_service');
    echo $service->greet(); // Output: Hello, PSR-11!
}

Conclusion

PSR-11 is an essential interface for modern PHP development, as it standardizes dependency management and resolution. It promotes flexibility and maintainability in application development.

 

 

 


PSR-7

PSR-7 is a PHP Standard Recommendation (PSR) that focuses on HTTP messages in PHP. It was developed by the PHP-FIG (Framework Interoperability Group) and defines interfaces for working with HTTP messages, as used by web servers and clients.

Key Features of PSR-7:

  1. Request and Response:
    PSR-7 standardizes how HTTP requests and responses are represented in PHP. It provides interfaces for:

    • RequestInterface: Represents HTTP requests.
    • ResponseInterface: Represents HTTP responses.
  2. Immutability:
    All objects are immutable, meaning that any modification to an HTTP object creates a new object rather than altering the existing one. This improves predictability and makes debugging easier.

  3. Streams:
    PSR-7 uses stream objects to handle HTTP message bodies. The StreamInterface defines methods for interacting with streams (e.g., read(), write(), seek()).

  4. ServerRequest:
    The ServerRequestInterface extends the RequestInterface to handle additional data such as cookies, server parameters, and uploaded files.

  5. Middleware Compatibility:
    PSR-7 serves as the foundation for middleware architectures in PHP. It simplifies the creation of middleware components that process HTTP requests and manipulate responses.

Usage:

PSR-7 is widely used in modern PHP frameworks and libraries, including:

Purpose:

The goal of PSR-7 is to improve interoperability between different PHP libraries and frameworks by defining a common standard for HTTP messages.

 


Lines of Code - LOC

"Lines of Code" (LOC) is a software development metric that measures the number of lines written in a program or application. This metric is often used to gauge the size, complexity, and effort required for a project. LOC is applied in several ways:

  1. Code Complexity and Maintainability: A high LOC count can suggest that a project is more complex or harder to maintain. Developers often aim to keep code minimal and efficient, as fewer lines typically mean fewer potential bugs and easier maintenance.

  2. Productivity Measurement: Some organizations use LOC to evaluate developer productivity, though the quality of the code—rather than just quantity—is essential. A high number of lines could also result from inefficient solutions or redundancies.

  3. Project Progress and Estimations: LOC can help in assessing project progress or in making rough estimates of the development effort for future projects.

While LOC is a simple and widely used metric, it has limitations since it doesn’t reflect code efficiency, readability, or quality.

 


Cyclomatic Complexity

Cyclomatic complexity is a metric used to assess the complexity of a program's code or software module. It measures the number of independent execution paths within a program, based on its control flow structure. Developed by Thomas J. McCabe, this metric helps evaluate a program’s testability, maintainability, and susceptibility to errors.

Calculating Cyclomatic Complexity

Cyclomatic complexity V(G)V(G) is calculated using the control flow graph of a program. This graph consists of nodes (representing statements or blocks) and edges (representing control flow paths between blocks). The formula is:

V(G)=E−N+2PV(G) = E - N + 2P

  • EE: The number of edges in the graph.
  • NN: The number of nodes in the graph.
  • PP: The number of connected components (for a connected graph, P=1P = 1).

In practice, a simplified calculation is often used by counting the number of branching points (such as If, While, or For loops).

Interpreting Cyclomatic Complexity

Cyclomatic complexity indicates the minimum number of test cases needed to cover each path in a program once. A higher cyclomatic complexity suggests a more complex and potentially error-prone codebase.

Typical Ranges and Their Meaning:

  • 1-10: Low complexity, easy to test and maintain.
  • 11-20: Moderate complexity, code becomes harder to understand and test.
  • 21-50: High complexity, code is difficult to test and error-prone.
  • 50+: Very high complexity, indicating a strong need for refactoring.

Benefits of Cyclomatic Complexity

By measuring cyclomatic complexity, developers can identify potential maintenance issues early and target specific parts of the code for simplification and refactoring.

 


Dephpend

Dephpend is a static analysis tool for PHP that focuses on analyzing and visualizing dependencies within a codebase. It provides insights into the architecture and structure of PHP projects by identifying the relationships between different components, such as classes and namespaces. Dephpend helps developers understand the coupling and dependencies in their code, which is crucial for maintaining a modular and scalable architecture.

Key Features of Dephpend:

  1. Dependency Graphs: It generates visual representations of how different parts of the application are interconnected.
  2. Architectural Analysis: Dephpend helps ensure that the architecture follows design principles, such as the Dependency Inversion Principle (DIP).
  3. Modularity: It helps identify areas where the code may be too tightly coupled, leading to poor modularity and making the code harder to maintain or extend.
  4. Layer Violations: Dephpend can spot violations where code in higher layers depends on lower layers inappropriately, aiding in cleaner architectural patterns like hexagonal architecture.

This tool is particularly useful in large codebases where maintaining a clear architecture is essential for scaling and reducing technical debt. By visualizing dependencies, developers can refactor code more confidently and ensure that new additions don't introduce unwanted complexity.

 


Deptrac

Deptrac is a static code analysis tool for PHP applications that helps manage and enforce architectural rules in a codebase. It works by analyzing your project’s dependencies and verifying that these dependencies adhere to predefined architectural boundaries. The main goal of Deptrac is to prevent tightly coupled components and ensure a clear, maintainable structure, especially in larger or growing projects.

Key features of Deptrac:

  1. Layer Definition: It allows you to define layers in your application (e.g., controllers, services, repositories) and specify how these layers are allowed to depend on each other.
  2. Violation Detection: Deptrac detects and reports when a dependency breaks your architectural rules, helping you maintain cleaner boundaries between components.
  3. Customizable Rules: You can customize the rules and layers based on your project’s architecture, allowing for flexibility in different application designs.
  4. Integration with CI/CD: It can be integrated into CI pipelines to automatically enforce architectural rules and ensure long-term code quality.

Deptrac is especially useful in maintaining decoupling and modularity, which is crucial in scaling and refactoring projects. By catching architectural violations early, it helps avoid technical debt accumulation.

 


Composer Unused

Composer Unused is a tool for PHP projects that helps identify unused dependencies in the composer.json file. It allows developers to clean up their list of dependencies and ensure that no unnecessary libraries are lingering in the project, which could bloat the codebase.

Features:

  • Scan for unused dependencies: Composer Unused scans the project's source code and compares the classes and functions actually used with the dependencies defined in composer.json.
  • List unused packages: It lists all the packages that are declared as dependencies in the composer.json but are not used in the project code.
  • Clean up composer.json: The tool helps identify and remove unused dependencies, making the project leaner and more efficient.

Usage:

Composer Unused is typically used in PHP projects to ensure that only the necessary dependencies are included. This can lead to better performance and reduced maintenance effort by eliminating unnecessary libraries.

 


Composer Require Checker

Composer Require Checker is a tool used to verify the consistency of dependencies in PHP projects, particularly when using the Composer package manager. It ensures that all the PHP classes and functions used in a project are covered by the dependencies specified in the composer.json file.

How it works:

  • Dependency verification: Composer Require Checker analyzes the project's source code and checks if all the necessary classes and functions used in the code are provided by the installed Composer packages.
  • Detect missing dependencies: If the code references libraries or functions that are not defined in the composer.json, the tool will flag them.
  • Reduce unnecessary dependencies: It also helps identify dependencies that are declared in the composer.json but are not actually used in the code, helping keep the project lean.

Usage:

This tool is particularly useful for developers who want to ensure that their PHP project is clean and efficient, with no unused or missing dependencies.