Params
in package
Class Params
Static request parameter handler with comprehensive RESTful support and focused DoS protection. Handles GET, POST, PUT, DELETE, PATCH requests with JSON, form-encoded, and multipart data.
FIXES APPLIED:
- ✅ POST multipart requests now properly use PHP's built-in $_FILES and $_POST data
- ✅ Files are always copied from $_FILES to self::$files during init()
- ✅ Method detection works even if Params::init() isn't called (with fallback)
- ✅ Raw input is not read for POST requests (already consumed by PHP)
RESTful verbs...
GET - Retrieve/read data. Safe & idempotent (no side effects, can repeat safely).
POST - Create new resources. Not idempotent (creates new thing each time).
PUT - Update/replace entire resource. Idempotent (same result if repeated).
PATCH - Partial update of resource. May or may not be idempotent.
DELETE - Remove resource. Idempotent (safe to repeat).
HEAD - Like GET but only returns headers (no body). For metadata/existence checks.
OPTIONS - Get allowed methods/capabilities for a resource. CORS preflight.
Primordyx framework supports all the main ones (GET, POST, PUT, DELETE) in both the Router and HttpClient classes. The Params class handles parsing request data for all these methods, which is especially important for PUT/PATCH/DELETE since PHP doesn't auto-populate $_POST for those.
SECURITY FEATURES (focused purely on DoS/memory protection):
- Request size limiting to prevent memory exhaustion attacks
- Line length validation to prevent buffer overflow attempts
- JSON depth limiting to prevent JSON bomb attacks
- Multipart boundary validation and part count limiting
- Filename sanitization and path traversal protection for uploads
- Dangerous file type blocking for uploads
- Secure temporary file creation with proper permissions
- Comprehensive security event logging via EventManager
- ALWAYS GRACEFUL: Never throws exceptions, always handles issues safely
- Defensive design: Log issues and continue with safe defaults
Tags
Table of Contents
Properties
- $files : array<string|int, mixed>
- $formData : array<string|int, mixed>
- $get : array<string|int, mixed>
- $inputData : array<string|int, mixed>
- $json : array<string|int, mixed>
- $maxChunkSize : int
- $maxInputSize : int
- $method : string
- $post : array<string|int, mixed>
- $rawInput : string
- $skipOnSecurityIssues : bool
Methods
- __wakeup() : mixed
- all() : array<string|int, mixed>
- Get all parameters with custom priority
- contentType() : string
- except() : array<string|int, mixed>
- Get all except specific keys
- files() : array<string|int, mixed>
- formData() : array<string|int, mixed>
- get() : mixed
- Retrieves request parameter with intelligent source prioritization and fallback handling.
- has() : bool
- Check if parameter exists
- init() : void
- Initialize and parse request parameters with comprehensive security protections.
- input() : mixed
- Accesses the intelligently merged input data with unified parameter access.
- isDelete() : bool
- isGet() : bool
- isMethod() : bool
- isPatch() : bool
- isPost() : bool
- isPut() : bool
- isRestMethod() : bool
- json() : array<string|int, mixed>
- method() : string
- only() : array<string|int, mixed>
- Get only specific keys
- rawInput() : string
- __clone() : mixed
- __construct() : mixed
- buildInputData() : void
- Builds unified input data structure with intelligent priority-based merging.
- createTempFileSafely() : string
- Safely create temporary file with security protections Never throws - returns empty string on failure.
- extractContentType() : string
- Extract content type from multipart headers
- parseInputData() : void
- Intelligently parses request content based on Content-Type header with maximum compatibility.
- parseMultipartData() : void
- Parses multipart/form-data with comprehensive security protections for file uploads.
- processMultipartFile() : void
- Processes individual multipart file uploads with comprehensive security validation.
- readInputSafely() : string
- Safely reads HTTP request body with comprehensive DoS protection mechanisms.
- validateInputContent() : bool
- Validates input content structure to prevent various DoS attacks.
- validateJsonDepth() : bool
- Validates JSON depth to prevent JSON bomb attacks.
Properties
$files
private
static array<string|int, mixed>
$files
= []
$formData
private
static array<string|int, mixed>
$formData
= []
$get
private
static array<string|int, mixed>
$get
= []
$inputData
private
static array<string|int, mixed>
$inputData
= []
$json
private
static array<string|int, mixed>
$json
= []
$maxChunkSize
private
static int
$maxChunkSize
= 8192
$maxInputSize
private
static int
$maxInputSize
= 52428800
$method
private
static string
$method
= ''
$post
private
static array<string|int, mixed>
$post
= []
$rawInput
private
static string
$rawInput
= ''
$skipOnSecurityIssues
private
static bool
$skipOnSecurityIssues
= true
Methods
__wakeup()
public
__wakeup() : mixed
all()
Get all parameters with custom priority
public
static all([array<string|int, mixed> $priority = ['get', 'input', 'post', 'json'] ]) : array<string|int, mixed>
Parameters
- $priority : array<string|int, mixed> = ['get', 'input', 'post', 'json']
Return values
array<string|int, mixed>contentType()
public
static contentType() : string
Return values
stringexcept()
Get all except specific keys
public
static except(array<string|int, mixed> $keys[, array<string|int, mixed> $priority = ['get', 'input', 'post', 'json'] ]) : array<string|int, mixed>
Parameters
- $keys : array<string|int, mixed>
- $priority : array<string|int, mixed> = ['get', 'input', 'post', 'json']
Return values
array<string|int, mixed>files()
public
static files() : array<string|int, mixed>
Return values
array<string|int, mixed>formData()
public
static formData() : array<string|int, mixed>
Return values
array<string|int, mixed>get()
Retrieves request parameter with intelligent source prioritization and fallback handling.
public
static get(string $key[, mixed|null $default = null ][, array<string|int, mixed> $priority = ['get', 'input', 'post', 'json'] ]) : mixed
This method provides the primary interface for accessing request parameters with built-in fallback logic that searches multiple data sources in priority order. It's designed to handle the complexity of modern web applications that may receive data via multiple channels (URL parameters, form data, JSON payloads) within a single request.
SEARCH PRIORITY (configurable): Default: ['get', 'input', 'post', 'json']
- 'get': URL query parameters ($_GET)
- 'input': Merged input data (smart combination of all sources)
- 'post': Traditional POST data ($_POST)
- 'json': Parsed JSON request body
- 'form': Form-encoded data from PUT/PATCH/DELETE requests
PRIORITY RATIONALE:
- GET parameters take precedence (explicit user intent via URL)
- Input data provides smart merged view of all body parameters
- POST data for backward compatibility with traditional applications
- JSON data as fallback for API-specific parameter access
COMMON USAGE PATTERNS:
Basic Parameter Access:
$name = Params::get('name'); // Search all sources
$email = Params::get('email', 'default'); // With default value
Source-Specific Access:
$id = Params::get('id', null, ['get']); // Only URL parameters
$data = Params::get('data', [], ['json', 'form']); // API data only
API Development:
$filters = Params::get('filters', [], ['get', 'json']); // URL or JSON
$sort = Params::get('sort', 'id', ['get']); // URL only
Form Processing:
$username = Params::get('username', '', ['post', 'form']); // Traditional or RESTful
FALLBACK BEHAVIOR:
- Searches sources in specified order
- Returns first non-null value found
- Returns default value if parameter not found in any source
- Maintains original data types (string, array, etc.)
DATA TYPE PRESERVATION:
- Strings: Returned as-is
- Arrays: Complex structures preserved
- Numbers: Maintains original type (string/int/float)
- Booleans: Preserved from JSON parsing
- Null: Treated as "not found", continues search
SECURITY CONSIDERATIONS:
- All data sources already validated during parsing
- No additional sanitization performed (use validation layer)
- Returns raw parameter values for application-level processing
- No automatic type coercion that could mask security issues
PERFORMANCE CHARACTERISTICS:
- O(p*s) where p is priority list length, s is source search time
- Early termination when parameter found
- Minimal overhead for cached/parsed data access
- No data copying during search process
ERROR HANDLING:
- Invalid source names: Silently ignored, continues search
- Missing data structures: Treated as empty, continues search
- No exceptions thrown regardless of input
DEBUGGING SUPPORT:
- Use source() method to determine where parameter originated
- Clear priority order for predictable behavior
- All original data sources remain accessible
Parameters
- $key : string
-
Parameter name to search for
- $default : mixed|null = null
-
Default value if parameter not found in any source
- $priority : array<string|int, mixed> = ['get', 'input', 'post', 'json']
-
List of source names in search order
Tags
Return values
mixed —Parameter value from first matching source, or default value
has()
Check if parameter exists
public
static has(string $key) : bool
Parameters
- $key : string
Return values
boolinit()
Initialize and parse request parameters with comprehensive security protections.
public
static init() : void
This method must be called once at the start of your application to parse the incoming HTTP request. It performs several critical security validations to protect against DoS attacks while maintaining maximum compatibility with legitimate requests.
SECURITY PROTECTIONS APPLIED:
- Memory exhaustion protection via size limits
- Buffer overflow protection via line length limits
- JSON bomb protection via nesting depth limits
- Multipart abuse protection via part count limits
- File upload security via type and path validation
GRACEFUL ERROR HANDLING:
- Never throws exceptions regardless of input
- Logs all security issues via EventManager for monitoring
- Continues processing with safe defaults when issues are detected
- Skips malicious/oversized content rather than crashing
PARSING BEHAVIOR:
- Attempts to parse JSON, form-encoded, and multipart data based on Content-Type
- Unknown content types are safely ignored (stored as raw data only)
- Combines all parsed data into smart priority-based access methods
- Maintains backward compatibility with traditional PHP request handling
MEMORY SAFETY:
- Reads input stream in small chunks to prevent memory spikes
- Enforces configurable size limits (50MB default, 0 = unlimited)
- Validates content structure before full parsing
- Automatically truncates oversized content rather than failing
USAGE: Call this method once during application bootstrap:
Params::init(); // Parse request with security protections
EVENTS FIRED:
- Params.security.request_too_large: When request exceeds size limits
- Params.security.input_stream_failed: When php://input cannot be opened
- Params.security.line_too_long: When input contains extremely long lines
- Params.security.json_too_deep: When JSON nesting exceeds safe limits
- Various multipart and file upload security events (see parseMultipartData)
Tags
input()
Accesses the intelligently merged input data with unified parameter access.
public
static input([string|null $key = null ][, mixed|null $default = null ]) : mixed
This method provides direct access to the merged input data structure created by buildInputData(). It represents the "best" view of all request parameters, combining data from multiple sources using smart prioritization rules. This is typically the preferred method for modern web applications and APIs.
TWO USAGE MODES:
-
BULK ACCESS (no parameters): Returns the complete merged parameter array containing all request data from all sources, resolved using priority rules.
-
SINGLE PARAMETER ACCESS (with key): Returns a specific parameter value from the merged data, with optional default value if the parameter doesn't exist.
MERGED DATA COMPOSITION: The returned data structure combines parameters from multiple sources:
- GET parameters (highest priority)
- Form-encoded data from request body
- JSON data from request body
- POST parameters (backward compatibility)
WHEN TO USE input() vs get():
Use input() when:
- You want the "smart merged" view of request data
- Building RESTful APIs with consistent parameter access
- You trust the priority system to resolve conflicts correctly
- Working with modern applications that mix parameter sources
Use get() when:
- You need explicit control over source priority
- Debugging parameter conflicts between sources
- Working with legacy applications with specific source requirements
- You need to override default priority behavior
EXAMPLE USAGE SCENARIOS:
RESTful API Controller:
// Get all request parameters for processing
$requestData = Params::input();
$user = new User($requestData);
// Get specific parameters with defaults
$limit = Params::input('limit', 20);
$offset = Params::input('offset', 0);
Form Processing:
// Handle both traditional forms and API requests
$username = Params::input('username');
$email = Params::input('email');
$preferences = Params::input('preferences', []);
Search/Filter Implementation:
// URL params override JSON body for flexibility
$filters = Params::input('filters', []);
$search = Params::input('q', '');
$page = Params::input('page', 1);
CONFLICT RESOLUTION EXAMPLES:
URL Override: Request: PUT /users/123?status=active with JSON: {"status": "inactive"} Result: Params::input('status') returns "active"
Complementary Data: Request: POST /search?q=php with Form: {"category": "tutorials"} Result: Params::input() returns {"q": "php", "category": "tutorials"}
DATA TYPE PRESERVATION:
- Maintains original data types from parsing
- JSON booleans remain boolean, not converted to strings
- Arrays and objects preserved as complex structures
- Numbers maintain their original representation
SECURITY CONSIDERATIONS:
- All data already validated during request parsing
- No additional sanitization applied (responsibility of application)
- Priority rules prevent parameter pollution attacks
- Returns raw values for application-level validation/sanitization
PERFORMANCE CHARACTERISTICS:
- Bulk access: O(1) direct array access
- Single parameter: O(1) hash table lookup
- No data copying, returns references to existing structures
- Minimal overhead compared to manual source checking
NULL vs MISSING DISTINCTION:
- Null values: Explicitly set null values are preserved and returned
- Missing keys: Return the provided default value
- Empty strings: Preserved as empty strings, not treated as missing
DEBUGGING SUPPORT:
- Use source() method to determine original parameter source
- Compare with individual source methods (json(), formData(), etc.)
- Predictable priority rules for conflict resolution
Parameters
- $key : string|null = null
-
Optional parameter name for single value access
- $default : mixed|null = null
-
Default value returned if key not found (single access mode only)
Tags
Return values
mixed —Full parameter array (bulk access) or single parameter value
isDelete()
public
static isDelete() : bool
Return values
boolisGet()
public
static isGet() : bool
Return values
boolisMethod()
public
static isMethod(string $verb) : bool
Parameters
- $verb : string
Return values
boolisPatch()
public
static isPatch() : bool
Return values
boolisPost()
public
static isPost() : bool
Return values
boolisPut()
public
static isPut() : bool
Return values
boolisRestMethod()
public
static isRestMethod() : bool
Return values
booljson()
public
static json() : array<string|int, mixed>
Return values
array<string|int, mixed>method()
public
static method() : string
Return values
stringonly()
Get only specific keys
public
static only(array<string|int, mixed> $keys[, array<string|int, mixed> $priority = ['get', 'input', 'post', 'json'] ]) : array<string|int, mixed>
Parameters
- $keys : array<string|int, mixed>
- $priority : array<string|int, mixed> = ['get', 'input', 'post', 'json']
Return values
array<string|int, mixed>rawInput()
public
static rawInput() : string
Return values
string__clone()
private
__clone() : mixed
__construct()
private
__construct() : mixed
buildInputData()
Builds unified input data structure with intelligent priority-based merging.
private
static buildInputData() : void
This method creates a single, unified view of all request parameters by intelligently combining data from multiple sources (GET, POST, form-encoded, JSON) using a priority system that matches common web development expectations and RESTful API patterns.
PRIORITY HIERARCHY (highest to lowest):
- GET parameters ($_GET) - Highest priority
- Form-encoded data (parsed from request body)
- JSON data (parsed from request body)
- POST parameters ($_POST) - Lowest priority
PRIORITY RATIONALE:
GET Parameters (Highest Priority):
- Explicitly visible in URL, user's clear intent
- Common pattern for filtering, pagination, sorting
- Should override any conflicting body parameters
- Example: /users?limit=10 should override body {"limit": 20}
Form-Encoded Data (High Priority):
- Traditional web form submissions
- More specific than JSON for field-level data
- Handles PUT/PATCH form submissions properly
- Maintains backward compatibility with form-based workflows
JSON Data (Medium Priority):
- Modern API standard for structured data
- Excellent for complex nested data structures
- Lower priority allows form overrides for specific fields
- Common in RESTful API implementations
POST Parameters (Lowest Priority):
- Included for backward compatibility only
- Usually redundant with form-encoded data
- Serves as fallback for edge cases
- Ensures no data is lost during transition
MERGING BEHAVIOR:
- Later sources in priority order overwrite earlier sources
- Only overwrites specific keys, not entire data structures
- Preserves unique keys from all sources
- Maintains data type integrity during merging
EXAMPLE MERGING SCENARIOS:
Scenario 1 - Parameter Override: JSON: {"name": "John", "age": 25} Form: {"name": "Jane"} GET: {"age": 30} Result: {"name": "Jane", "age": 30}
Scenario 2 - Complementary Data: JSON: {"user": {"name": "John"}} Form: {"action": "update"} GET: {"debug": "true"} Result: {"user": {"name": "John"}, "action": "update", "debug": "true"}
Scenario 3 - Complex Structures: JSON: {"filters": {"status": "active", "type": "user"}} GET: {"filters": {"status": "inactive"}} Result: {"filters": {"status": "inactive"}} (GET overrides entire filters object)
API DESIGN BENEFITS:
- Single input() method provides all request data
- Predictable priority system reduces confusion
- Supports both traditional forms and modern APIs
- Enables flexible parameter passing strategies
COMPATIBILITY CONSIDERATIONS:
- Maintains access to individual data sources (json(), formData(), etc.)
- Doesn't modify original source data structures
- Backward compatible with existing parameter access patterns
- Supports gradual migration from traditional to RESTful patterns
MEMORY EFFICIENCY:
- Merging creates new references, not data copies
- Array merge operations are optimized by PHP
- Minimal memory overhead for the unified view
- Original data structures remain available
EDGE CASE HANDLING:
- Empty data sources: Safely ignored during merging
- Null values: Preserved and can override non-null values
- Mixed data types: Preserved without type coercion
- Nested arrays: Replaced entirely, not merged recursively
SECURITY IMPLICATIONS:
- No additional security risks from merging process
- All data sources already validated before merging
- Priority system prevents parameter pollution attacks
- No data transformation that could introduce vulnerabilities
DEBUGGING AND OBSERVABILITY:
- Merged data available via input() method
- Original sources remain accessible for debugging
- Clear priority rules for predictable behavior
- Source tracking available via source() method
PERFORMANCE CHARACTERISTICS:
- O(n) where n is total number of parameters across all sources
- Minimal CPU overhead for array operations
- Memory usage proportional to unique parameter count
- Executed once per request during initialization
Tags
createTempFileSafely()
Safely create temporary file with security protections Never throws - returns empty string on failure.
private
static createTempFileSafely(string $data) : string
Parameters
- $data : string
Return values
string —Temporary file path, or empty string on failure
extractContentType()
Extract content type from multipart headers
private
static extractContentType(string $headers) : string
Parameters
- $headers : string
Return values
stringparseInputData()
Intelligently parses request content based on Content-Type header with maximum compatibility.
private
static parseInputData() : void
This method implements a sophisticated content parsing system that handles multiple data formats commonly used in RESTful APIs and web applications. It's designed to maximize compatibility while maintaining security through defensive parsing practices.
SUPPORTED CONTENT TYPES:
- application/json: Standard JSON API requests
- application/x-www-form-urlencoded: Traditional HTML form submissions
- multipart/form-data: File uploads and complex form data
- Unknown types: Safely stored as raw data without parsing
PARSING STRATEGY BY TYPE:
JSON (application/json):
- Uses built-in json_decode with strict array mode
- Handles malformed JSON gracefully (returns empty array)
- Preserves nested data structures for complex APIs
- Already protected by validateJsonDepth() against JSON bombs
- Stores result in $json property for direct access
Form-Encoded (application/x-www-form-urlencoded):
- Uses parse_str() to convert URL-encoded data to array
- Only processes for PUT/PATCH/DELETE (POST handled by PHP automatically)
- Handles complex field names like arrays: field[key]=value
- Stores result in $formData property for consistent access
- Maintains compatibility with traditional form processing
Multipart (multipart/form-data):
- Custom parser for file uploads via non-POST methods
- Handles mixed content: text fields + binary files
- Implements comprehensive security validations (see parseMultipartData)
- Populates both $formData (fields) and $files (uploads)
- FIXED: Now processes for ALL methods including POST
Unknown Content Types:
- No parsing attempted (security by design)
- Content stored as raw data only
- No errors generated (graceful degradation)
- Application can access via rawInput() if needed
- Prevents parser vulnerabilities from unknown formats
METHOD-SPECIFIC BEHAVIOR:
GET Requests:
- No request body parsing (follows HTTP semantics)
- Only $_GET parameters processed
- Raw input ignored (GET shouldn't have request body)
POST Requests:
- FIXED: Now properly handles multipart data via PHP's built-in parsing
- Files from $_FILES are copied to self::$files during init()
- FormData mirrors $_POST for API consistency
- Maintains backward compatibility with existing code
PUT/PATCH/DELETE Requests:
- Full custom parsing (PHP doesn't auto-parse these)
- Enables RESTful API support with proper data access
- Handles all content types that POST supports
- Essential for modern API development
SECURITY CONSIDERATIONS:
- Never attempts to parse untrusted/unknown formats
- All parsing operations are defensive (handle malformed input)
- Size and structure already validated before parsing
- Parser failures result in empty data, not crashes
- No execution of dynamic content during parsing
ERROR HANDLING PHILOSOPHY:
- Malformed JSON: Results in empty array, continues processing
- Invalid form data: Skips malformed fields, processes valid ones
- Multipart errors: Detailed handling in parseMultipartData()
- Unknown formats: Gracefully ignored, no error conditions
- Parser exceptions: Caught and handled without application impact
COMPATIBILITY NOTES:
- Maintains full backward compatibility with traditional PHP request handling
- Extends PHP's capabilities to handle RESTful methods properly
- No interference with existing $_GET, $_POST, $_FILES usage
- Additional data available through enhanced access methods
PERFORMANCE CHARACTERISTICS:
- JSON parsing: O(n) where n is JSON size, efficient built-in parser
- Form parsing: O(n) URL decoding, minimal overhead
- Multipart parsing: O(m) where m is number of parts, custom implementation
- Unknown types: O(1) no parsing overhead
- Memory usage: Proportional to parsed data size, not raw input size
EXTENSIBILITY:
- Easy to add support for new content types (XML, MessagePack, etc.)
- Modular design allows format-specific security validations
- Parser selection based on Content-Type header inspection
- Graceful fallback for unsupported types
Tags
parseMultipartData()
Parses multipart/form-data with comprehensive security protections for file uploads.
private
static parseMultipartData() : void
This method implements a custom multipart parser necessary for handling file uploads via PUT, PATCH, and DELETE requests (PHP only auto-parses multipart for POST). It includes extensive security validations to prevent various attack vectors commonly associated with file upload functionality.
IMPORTANT: This parser is NOT used for POST requests because:
- PHP automatically handles POST multipart and populates $_POST and $_FILES
- php://input is already consumed by PHP for POST requests
- POST multipart data is handled in init() by copying $_FILES to self::$files
WHY CUSTOM PARSER IS NEEDED FOR NON-POST METHODS:
- PHP only populates $_POST and $_FILES for POST requests
- RESTful APIs need file upload support for PUT/PATCH operations
- Built-in parser doesn't provide necessary security controls
- Custom implementation allows fine-grained security policies
MULTIPART FORMAT OVERVIEW:
- Content separated by boundary strings defined in Content-Type header
- Each part has headers (Content-Disposition, Content-Type) and data
- Parts can contain form fields (text) or file uploads (binary)
- Complex nested structures possible (arrays, objects)
SECURITY PROTECTIONS IMPLEMENTED:
- BOUNDARY VALIDATION:
- Purpose: Prevent parser confusion and resource exhaustion
- Validation: Boundary must be present and reasonable length (< 256 chars)
- Attack vector: Missing or extremely long boundaries can cause parser issues
- Handling: Skip processing entirely if boundary is invalid
- PART COUNT LIMITING:
- Purpose: Prevent resource exhaustion via excessive form parts
- Limit: Maximum 1000 parts per request
- Attack vector: Requests with millions of empty parts to consume memory/CPU
- Handling: Stop processing after limit reached, log security event
- HEADER SIZE VALIDATION:
- Purpose: Prevent buffer overflow attacks via oversized headers
- Limit: 8KB per part's headers
- Attack vector: Extremely long Content-Disposition or other headers
- Handling: Skip individual parts with oversized headers
- FIELD NAME VALIDATION:
- Purpose: Prevent various injection and parsing attacks
- Validation: Alphanumeric plus underscore, brackets, hyphen only
- Length limit: 255 characters maximum
- Attack vector: Field names with special characters, path traversal, etc.
- Handling: Skip parts with invalid field names
- FIELD SIZE LIMITING:
- Purpose: Prevent memory exhaustion via oversized form fields
- Limit: 1MB per individual form field
- Attack vector: Single form field containing GB of data
- Handling: Skip oversized fields, continue processing others
- FILE UPLOAD SECURITY:
- Comprehensive file validation in processMultipartFile()
- Filename sanitization and path traversal protection
- File type validation and dangerous type blocking
- Individual file size limits
- Secure temporary file creation with restricted permissions
PARSING ALGORITHM:
- Extract and validate boundary from Content-Type header
- Split raw data by boundary markers
- Process each part individually with security checks
- Parse headers using regex with size limits
- Validate Content-Disposition header for field name and filename
- Apply security validations based on content type (field vs file)
- Store validated data in appropriate collections
ERROR HANDLING STRATEGY:
- Malformed parts: Skip individual parts, continue processing others
- Invalid headers: Log and skip, don't fail entire request
- Security violations: Log detailed events, skip violating content
- Boundary issues: Skip entire multipart processing
- Resource limits: Stop processing, return partial results
MEMORY EFFICIENCY:
- Processes parts sequentially, not all at once
- Immediately validates and rejects oversized content
- No unnecessary data copying during processing
- Temporary files created only for valid uploads
- Progressive parsing reduces peak memory usage
SECURITY EVENT LOGGING:
- Boundary validation failures
- Part count limit exceeded
- Header size violations
- Invalid field names
- Field size violations
- File upload security events
- Processing completion statistics
COMPATIBILITY NOTES:
- Handles standard RFC 7578 multipart/form-data format
- Compatible with most HTTP clients and browsers
- Supports nested field names (arrays, objects)
- Maintains compatibility with $_FILES structure for uploads
ATTACK SCENARIOS PREVENTED:
- Resource exhaustion via thousands of tiny parts
- Memory exhaustion via oversized individual parts
- Parser confusion via malformed boundaries
- Buffer overflow via extremely long headers
- Path traversal via malicious filenames
- Code execution via dangerous file types
- Temporary file attacks via insecure file creation
PERFORMANCE CHARACTERISTICS:
- Linear processing: O(n) where n is number of parts
- Memory usage: O(largest_part) not O(total_size)
- Early rejection: Invalid content rejected before expensive processing
- Streaming approach: Processes data as it's encountered
Tags
processMultipartFile()
Processes individual multipart file uploads with comprehensive security validation.
private
static processMultipartFile(string $name, string $filename, string $headers, string $data) : void
This method handles the secure processing of file uploads from multipart/form-data requests. It implements multiple layers of security validation to prevent common file upload attack vectors while maintaining compatibility with legitimate uploads.
SECURITY VALIDATIONS IMPLEMENTED:
- FILENAME LENGTH ATTACKS:
- Attack: Extremely long filenames to cause buffer overflows
- Protection: 255 character limit (filesystem standard)
- Action: Reject oversized filenames, continue processing
- Rationale: Most filesystems have 255 char filename limits
- PATH TRAVERSAL ATTACKS:
- Attack: Filenames containing ../ or ..\ to escape upload directory
- Protection: Pattern detection and rejection
- Action: Reject suspicious filenames, log attempt
- Rationale: Prevents files from being written outside intended directory
- FILE SIZE ATTACKS:
- Attack: Extremely large files to exhaust disk space or memory
- Protection: 10MB limit per individual file
- Action: Reject oversized files, log attempt, continue processing
- Rationale: Prevents single files from consuming excessive resources
- DANGEROUS FILE TYPE ATTACKS:
- Attack: Upload executable files that could be executed on server
- Protection: Block known dangerous MIME types
- Dangerous types: PHP scripts, executables, shell scripts
- Action: Reject dangerous types, log attempt, continue processing
- Note: Content-Type can be spoofed, additional validation recommended
- TEMPORARY FILE ATTACKS:
- Attack: Exploit insecure temporary file creation
- Protection: Secure temp file creation with restricted permissions (0600)
- Location: Dedicated upload directory with proper isolation
- Cleanup: Automatic cleanup on script termination
VALIDATION SEQUENCE:
- Filename length validation (< 255 characters)
- Path traversal detection (../ and ..\ patterns)
- File size validation (< 10MB per file)
- Content-Type extraction and validation
- Dangerous file type detection
- Secure temporary file creation
- Data writing with integrity verification
- File structure population for application use
DANGEROUS FILE TYPES BLOCKED:
- application/x-php: PHP scripts
- application/x-httpd-php: Alternative PHP MIME type
- text/x-php: PHP source files
- application/x-executable: Binary executables
- application/x-msdownload: Windows executables
- application/x-sh: Shell scripts
SECURE FILE HANDLING:
- Temporary files created with 0600 permissions (owner read/write only)
- Files stored in isolated temporary directory
- Automatic cleanup prevents temporary file accumulation
- Basename() used to strip path information from filenames
- Content integrity verified during write operations
COMPATIBILITY WITH PHP $_FILES:
- Maintains standard $_FILES array structure
- Compatible with existing file upload processing code
- Standard error codes (UPLOAD_ERR_OK)
- Consistent field naming and data types
ERROR HANDLING PHILOSOPHY:
- Individual file failures don't affect other files
- Detailed logging for security analysis
- Graceful degradation: skip problematic files, continue processing
- No exceptions thrown regardless of input
SECURITY EVENT LOGGING: Each validation failure generates detailed events including:
- Specific validation failure reason
- Original filename and field name
- File size and content type
- IP address and user agent (for attack attribution)
- Timestamp and request context
PERFORMANCE CONSIDERATIONS:
- Validations performed in order of computational cost (cheap first)
- Early rejection prevents expensive operations on invalid files
- Streaming file creation avoids memory duplication
- Efficient pattern matching for security validations
DEFENSE IN DEPTH: This method provides the first layer of file upload security. Additional recommended protections include:
- Virus scanning of uploaded files
- File content validation (magic number checking)
- Sandboxed execution environment for file processing
- Regular cleanup of temporary directories
- Monitoring for unusual upload patterns
USAGE NOTES:
- Called automatically during multipart parsing
- Creates entries in self::$files array for valid uploads
- Invalid files are silently skipped with security logging
- Application should verify file existence before use
Parameters
- $name : string
-
Form field name for the file upload
- $filename : string
-
Original filename from client
- $headers : string
-
Raw headers from multipart section
- $data : string
-
Raw binary file data
Tags
readInputSafely()
Safely reads HTTP request body with comprehensive DoS protection mechanisms.
private
static readInputSafely() : string
This method implements multiple layers of protection against memory exhaustion attacks while maintaining compatibility with legitimate large requests. It's designed to prevent attackers from crashing your application by sending extremely large request bodies.
ATTACK VECTORS PREVENTED:
- Memory exhaustion: Attackers sending GB-sized requests to consume all available memory
- Resource starvation: Multiple concurrent large requests overwhelming the server
- Application crashes: Malformed or oversized content causing PHP memory limit errors
PROTECTION MECHANISMS:
- Content-Length validation: Checks declared size before reading any data
- Chunked reading: Reads data in small chunks (8KB default) to prevent memory spikes
- Progressive size checking: Monitors actual bytes read during streaming
- Automatic truncation: Safely limits content to maximum allowed size
- Stream failure handling: Gracefully handles I/O errors without crashing
SECURITY EVENT LOGGING:
- Request size violations with actual vs allowed sizes
- Stream access failures with error context
- Progressive size monitoring for attack pattern detection
- Successful truncation events for forensic analysis
MEMORY CHARACTERISTICS:
- Peak memory usage: O(maxChunkSize) not O(requestSize)
- CPU overhead: O(requestSize / chunkSize) linear streaming
- I/O efficiency: Stream-based reading with optimal chunk sizes
- Memory safety: Automatic garbage collection of processed chunks
TRUNCATION BEHAVIOR:
- Truncates at maxInputSize boundary, preserving partial content
- Logs truncation events for security monitoring
- Continues processing with partial content rather than failing
- Provides application-level indication of truncation occurrence
COMPATIBILITY NOTES:
- Compatible with all HTTP methods and content types
- Works with both declarative (Content-Length) and chunked transfer encoding
- Handles edge cases like empty requests and malformed headers gracefully
- No interference with PHP's built-in request handling for supported methods
PERFORMANCE OPTIMIZATIONS:
- Early size validation prevents unnecessary I/O for oversized requests
- Optimal chunk size balances memory usage and I/O efficiency
- Progressive validation reduces latency for size violations
- Stream-based approach minimizes memory allocation overhead
Tags
Return values
string —Raw request body content (possibly truncated if oversized)
validateInputContent()
Validates input content structure to prevent various DoS attacks.
private
static validateInputContent() : bool
This method performs lightweight structural validation of request content to identify and reject potentially malicious payloads before expensive parsing operations. It's designed to catch common attack patterns while maintaining very low false positive rates.
VALIDATION CHECKS PERFORMED:
- LINE LENGTH VALIDATION:
- Purpose: Prevent buffer overflow attacks via extremely long lines
- Limit: 64KB per line (accommodates legitimate large content)
- Attack vector: Single lines with millions of characters
- Performance: O(n) linear scan, very fast
- JSON BOMB PROTECTION:
- Purpose: Prevent exponential memory/CPU consumption via nested JSON
- Method: Depth limit validation using PHP's built-in parser controls
- Limit: 32 levels of nesting (reasonable for legitimate use)
- Attack vector: Deeply nested JSON structures that expand exponentially
DESIGN PHILOSOPHY:
- Structural validation only: No semantic content analysis
- Fast rejection: Identifies obvious attacks quickly
- Low false positives: Conservative limits accommodate legitimate use cases
- Defensive parsing operations
- Comprehensive: Multiple validation layers for different attack vectors
- Observable: All rejections logged with detailed context for investigation
FALSE POSITIVE PREVENTION:
- Line length limit chosen to accommodate legitimate large content
- JSON depth limit allows for complex but reasonable data structures
- No content-based pattern matching (removed to prevent false positives)
- Focus on structural rather than semantic content validation
PERFORMANCE IMPACT:
- Line scanning: O(n) where n is content length, very fast
- JSON validation: O(1) depth check using built-in parser limits
- Memory usage: O(1) - no content duplication during validation
- CPU usage: Minimal overhead, linear scan of content
ERROR HANDLING:
- Invalid content: Logs event, returns false, calling code handles gracefully
- Validation errors: Never throws exceptions, always returns boolean result
- System errors: Treats as validation failure, logs and continues
- Edge cases: Empty content always passes validation (safe default)
INTEGRATION WITH PARSING:
- Called before expensive parsing operations (JSON, multipart)
- Provides early rejection of obviously malicious content
- Allows parsers to operate on pre-validated, safer content
- Reduces attack surface by filtering content before complex processing
MONITORING CAPABILITIES:
- Detailed logging of all validation failures with context
- Performance metrics for validation operations
- Content samples (truncated) for security analysis
- IP tracking for attack pattern identification
Tags
Return values
bool —True if content structure is safe for processing, false if potentially dangerous
validateJsonDepth()
Validates JSON depth to prevent JSON bomb attacks.
private
static validateJsonDepth() : bool
Never throws - always returns safe assessment.
Return values
bool —True if JSON is safe, false if too deep