Essential Webman Development Standards and Best Practices

This guide outlines Webman’s latest development conventions, covering PHP version selection, naming rules, memory-resident processes, logging, routing, deployment, controller design, database queries, security measures, and more to help developers write clean, efficient, and secure code.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Essential Webman Development Standards and Best Practices

Webman is a high‑performance, memory‑resident PHP framework. For new projects, use PHP 8.2+ to benefit from better performance, while Webman 1.6.0 requires at least PHP 8.0. Upgrade instructions are available at https://www.workerman.net/doc/webman/upgrade/1-6.html. Some extensions may not support the latest PHP versions, so choose the appropriate version or find compatible extensions.

Basic Naming Conventions

Webman follows PSR‑2 and PSR‑4 autoloading standards. Violating these can cause functional issues.

Class and File Naming

Class (including interfaces and Trait) filenames must match the class name and use PascalCase.

Function files, configuration files, and route definition files use lowercase naming.

All files, whether classes or plain scripts, must have a .php extension.

Directory names use lowercase singular form.

Template files use lowercase naming.

Configuration and Variable Naming

Configuration parameter names use lowercase.

Constants and environment variables use uppercase.

Function, Method, and Property Naming

Functions use lowercase with underscores, e.g., generate_order_no.

Methods use camelCase starting with a lowercase letter, e.g., getUserName.

Properties use camelCase starting with a lowercase letter, e.g., tableName or instance.

Magic methods start with double underscores, e.g., __call, __callStatic.

Memory‑Resident Process

Webman keeps PHP files in memory as opcode. After changing business code or configuration, run php start.php reload. For process‑related changes or new Composer packages, restart with php start.php restart. A built‑in monitor process reloads automatically in Workerman debug mode (started without -d). Windows users must run windows.bat or php windows.php to enable this.

Output Statements

In traditional php‑fpm projects, echo and var_dump output directly to the page. In Webman debug mode, such output appears in the terminal, not the page (except in template files).

Avoid Certain Statements

Calling die or exit terminates the worker, causing WORKER EXIT UNEXPECTED errors. Use return instead. sleep pauses the process, halting all client requests. pcntl_fork is prohibited because Webman does not allow manual process creation. Avoid infinite loops in business code, as they block the framework from handling other requests.

IDE and Code Style

Standardize on a single IDE and enforce PSR‑1 and PSR‑2 coding standards. If a unified IDE is impossible, ensure at least PSR‑1/PSR‑2 compliance.

Helper Functions

Helper functions simplify code but can be overused. Understand their internal implementation before adopting them. Define custom helpers in functions.php if needed.

Logging Standards

Use PSR‑3 logging methods directly, e.g., Log::info('message') or Log::error('error'). Supported levels include debug, info, notice, warning, error, critical, alert, emergency, and sql. Set $maxFiles to limit log file count and prevent disk exhaustion.

Routing Standards

Default route pattern: http://127.0.0.1:8787/{controller}/{action}. Default controller: app\controller\IndexController, default action: index.

Disable Routing

Route::disableDefaultRoute();

Define Request Types

Prefer explicit methods, e.g., Route::get('hello/{id}', 'index/hello'); over generic Route::add(['GET'], ...).

Route Path Prefix

Routes must start with /. Incorrect: Route::any('test', ...). Correct: Route::any('/test', ...).

Route Grouping

Use groups to improve performance:

Route::group('/blog', function () {
    Route::get(':id$', 'blog/read');
    Route::get(':id/edit$', 'blog/edit');
});

Avoid flat definitions without groups.

Route Variables

Define parameters with {key} and access them in controller methods:

Route::any('/user/{id}', [app\controller\UserController::class, 'get']);

class UserController {
    public function get(Request $request, $id) {
        return response('Received '.$id);
    }
}

Deployment Guidelines

Point the web root to the public directory, not the project root. Keep only the entry script and static assets in public. Use consistent domain names for testing (e.g., webman.test) instead of localhost. Disable debug mode in production by setting 'debug' => false in the environment configuration.

.gitignore

Typical entries:

/runtime
/.idea
/.vscode
/vendor
*.log
.env
/tests/tmp
/config/thinkorm.php

Only commit composer.json and composer.lock, then run composer install on the server.

Documentation

Add a readme.md at the project root following Markdown conventions. Include API documentation for front‑end integration.

Controller Standards

Enable controller suffixes (default Controller) in config/app.php to avoid naming conflicts. Controllers should be lightweight, delegate validation to validators, and return responses via return. Use middleware for cross‑cutting concerns instead of overriding initialization methods.

Database Naming Conventions

Tables and columns use lowercase with underscores, e.g., resty_user, user_name.

Primary key: id. Foreign keys: resource_id (e.g., user_id).

Add create_time and update_time (datetime) to every table; optionally delete_time for soft deletes.

Model classes should extend a common base class and define autoWriteTimestamp for ThinkORM.

Query Standards

Never configure DB connections outside configuration files. Prefer the query builder over raw SQL. Use migrations for schema changes. Perform queries via Db or model static methods, e.g., Db::name('user')->where(...)->select(). Use whereNull / whereNotNull for NULL checks, and fieldRaw, orderRaw, whereRaw or whereExp for SQL functions. Avoid heavy data processing in web requests; use CLI commands for large jobs.

Conditional Queries

User::when($condition, function ($query) {
    $query->where('score', '>', 80)->limit(10);
})->select();

JSON Fields

Define JSON attributes in the model: protected $json = ['info']; Query with where('info->nickname', 'webman') or via

Db::name('user')->json(['info'])->where('info->nickname', 'webman')->find();</p>
<h3>SQL Functions</h3>
<pre><code>User::whereExp('nickname', "= CONCAT(name, '-', id)")
    ->whereRaw('LEFT(nickname, 5) = ?', ['think'])
    ->select();

Increment/Decrement

Blog::where('id', 10)
    ->inc('read_count')
    ->dec('comment_count', 2)
    ->save();

Custom Order

User::where('status', 1)
    ->orderField('id', [1,2,3])
    ->select();

Security Practices

Enable file upload validation (extension, MIME type, size, image integrity). Use validators via validate() in controllers; model‑level validation is deprecated. Protect against XSS by ensuring all output is escaped with htmlentities (Webman 5.1 does this automatically). Implement CSRF protection with form tokens, enforce proper HTTP methods ( POST , PUT , PATCH , DELETE ) for state‑changing actions, and keep GET read‑only.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Deploymentcoding standardsroutingSecurityPHPWebmanDatabase Queries
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.