Skip to content

ThinkPHP 8 Best Practices for API Development

This document serves as a guide for developing APIs within the Stooland project using ThinkPHP 8. It outlines standard practices to ensure consistency, maintainability, and proper debugging capabilities.

1. Logging

Do NOT use: error_log(), var_dump(), print_r()USE: think\facade\Log

Using the framework's logging facade ensures that logs are correctly routed, formatted, and stored in the runtime directory (runtime/log/), making them accessible for debugging and monitoring.

Usage Examples

php
use think\facade\Log;

// Info level (General flow, key events)
Log::info('[ModuleName] Action started with params: ' . json_encode($params));

// Error level (Exceptions, critical failures)
Log::error('[ModuleName] Failed to process request: ' . $exception->getMessage());

// Debug level (Detailed data for troubleshooting - ensure this is not too verbose in production)
Log::debug('[ModuleName] API Response: ' . $rawResponse);

Contextual Logging

Always include a prefix or context identifier (e.g., [VolcengineLLM]) to make it easier to filter logs.

php
Log::info("[VolcengineLLM] ImageGen Req: URL={$url}, Key={$maskKey}");

2. Request Handling

Do NOT use: $_GET, $_POST, $_REQUESTUSE: $this->request or $this->getParams() (if extending ApiBaseController)

Getting Parameters

php
// In a controller extending ApiBaseController
$params = $this->getParams(); // Get all params
$specific = $this->getParams('key', 'default_value'); // Get specific param with default

Input Validation

Always validate input before processing.

php
if (empty($params['req_key'])) {
    return $this->sendResponse(ERROR_LOGIC, [], 'Missing required parameter: req_key');
}

3. Response Formatting

Do NOT use: json_encode(), echo, dieUSE: $this->sendResponse() (if extending ApiBaseController)

Standardizing responses ensures frontend clients can consistently parse success and error states.

php
// Success
return $this->sendResponse(0, $data);

// Error with custom message
return $this->sendResponse(ERROR_LOGIC, [], 'Something went wrong');

4. Exception Handling

Wrap logic in try-catch blocks to prevent unhandled exceptions from exposing stack traces to the client (unless in debug mode) and to provide meaningful error messages.

php
try {
    // Business logic
} catch (\Throwable $e) {
    Log::error('[ModuleName] Exception: ' . $e->getMessage());
    return $this->sendResponse(ERROR_LOGIC, [], 'Operation failed: ' . $e->getMessage());
}

5. Service Layer

Keep controllers thin. Business logic should reside in Service classes.

  • Controllers: Handle HTTP request parsing, validation, and response formatting.
  • Services: Implement the actual business logic, database interactions, and external API calls.

6. Configuration & Environment

Do NOT use: Hardcoded credentials USE: .env file and Env::get()

php
use think\facade\Env;

$apiKey = Env::get('VOLCENGINE.ARK_KEY');

This document is a living guide. Please update it as new patterns or standards are adopted.