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.
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.phpOnly 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
