MySQLi set_local_infile_handler - Set LOAD DATA Handler
When working with MySQL and PHP’s MySQLi extension, the LOAD DATA LOCAL INFILE command is a powerful tool to efficiently import data from files into database tables. However, sometimes the default file loading behavior needs to be customized or overridden, especially when file sources are non-standard or when you want to process input data dynamically.
PHP’s MySQLi::set_local_infile_handler() method allows developers to define a callback function that intercepts and handles the data loading process requested by LOAD DATA LOCAL INFILE. This tutorial will guide you through the prerequisites, usage, and best practices of using this method.
Prerequisites
- PHP 7.1+ installed with MySQLi extension enabled
- MySQL server configured to allow
LOAD DATA LOCAL INFILE - Basic understanding of PHP and MySQLi procedural or object-oriented usage
- A MySQL database user with privileges to execute
LOAD DATA LOCAL INFILE
Setup Steps for Using set_local_infile_handler()
-
Establish a MySQLi connection with
mysqli_init()ornew mysqli(). -
Enable local infile support. Ensure the MySQL server and client support
LOAD DATA LOCAL INFILE. - Define a custom handler callback function to process or provide the file data.
-
Register the handler using
$mysqli->set_local_infile_handler(). -
Run your
LOAD DATA LOCAL INFILEquery as usual.
How set_local_infile_handler() Works
When executing a LOAD DATA LOCAL INFILE query, MySQLi normally reads the specified local file from the client filesystem and sends its contents to the MySQL server. By setting a local infile handler, you intercept this process and supply data programmatically.
The callback function must follow a specific interface set by the MySQLi extension:
- Receive instructions about the file path requested by the SQL command.
- Provide the data stream (as a resource or string chunks) to the query execution.
- Handle closing or cleanup when done or on errors.
Example: Custom Local Infile Handler in PHP
<?php
// Initialize MySQLi connection
$mysqli = new mysqli('localhost', 'username', 'password', 'database');
// Check connection
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') '
. $mysqli->connect_error);
}
// Define the local infile handler callback
$localInfileHandler = function ($command, $path, $mysqli) {
switch ($command) {
case MYSQLI_LOCAL_INFILE_INIT:
// Open your custom data source (could be a temp file or in-memory stream)
$data = "id,name,age\n1,John,23\n2,Jane,30\n3,Bob,25\n";
$stream = fopen('php://temp', 'r+');
fwrite($stream, $data);
rewind($stream);
return $stream; // Return stream resource to MySQLi
case MYSQLI_LOCAL_INFILE_READ:
// Copy data chunk from your stream to MySQLi buffer
return fread($path, 8192);
case MYSQLI_LOCAL_INFILE_END:
// Close your resource
fclose($path);
return true;
case MYSQLI_LOCAL_INFILE_ERROR:
// Handle error during local infile operation
error_log("Local infile error: " . $path);
return false;
}
};
// Set the handler
$mysqli->set_local_infile_handler($localInfileHandler);
// Prepare and execute the LOAD DATA LOCAL INFILE query
$sql = "LOAD DATA LOCAL INFILE 'dummy path ignored by handler'
INTO TABLE users
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(id, name, age)";
if ($mysqli->query($sql) === true) {
echo "Data loaded successfully via custom handler.";
} else {
echo "Error loading data: " . $mysqli->error;
}
// Close the connection
$mysqli->close();
?>
Note: The file path given in the SQL query ('dummy path ignored by handler') is not actually read because the handler takes over the data source. The handler supplies the data dynamically on the client side.
Best Practices
- Always validate and sanitize any data before feeding it into the handler to avoid SQL injection or data corruption.
- Use streams like
php://temporphp://memoryfor efficient memory management. - Implement error logging inside the handler for easier debugging.
- Close streams and free resources during the
MYSQLI_LOCAL_INFILE_ENDphase to prevent memory leaks. - Test handler logic independently before integrating with complex LOAD DATA queries.
Common Mistakes
- Skipping the initialization phase and not returning a valid stream resource causes the query to fail.
- Not handling the read phase correctly results in partial or empty data imports.
- Using an actual file path in the SQL without realizing the handler overrides it can cause confusion.
- Forgetting to enable
local_infilesupport in the MySQL client or server prevents LOAD DATA LOCAL INFILE from working. - Ignoring error handling callbacks can make debugging difficult.
Interview Questions
Junior Level
- What does
set_local_infile_handler()do in MySQLi?
It sets a callback function to handle data loading operations when usingLOAD DATA LOCAL INFILEin MySQLi. - Why would you use a local infile handler instead of a regular file path?
To supply data dynamically or from custom sources rather than from physical files on disk. - Which PHP extension provides the
set_local_infile_handler()method?
The MySQLi extension provides it. - What kind of resource does the callback need to return during initialization?
It should return a stream resource (e.g., from fopen) that MySQLi will read from. - Can
LOAD DATA LOCAL INFILEfunction without enabling local_infile support?
No, both the client and server must allow local_infile for it to work.
Mid Level
- Explain the phases your callback must handle in
set_local_infile_handler().
The phases are: initialization, read chunks of data, end/close the stream, and error handling. - What happens if your handler returns false during the init phase?
The LOAD DATA LOCAL INFILE query will fail because no valid data stream is provided. - How can you handle large data efficiently inside the handler?
By reading and sending data in chunks instead of loading everything into memory at once. - How do you register a handler function using an object-oriented MySQLi connection?
Use$mysqli->set_local_infile_handler(callback_function)on your MySQLi instance. - Is it possible to process data line-by-line inside the local infile handler?
Yes, by implementing custom logic within the read phase to read and process data as needed.
Senior Level
- How would you integrate encryption/decryption logic in the local infile handler?
By intercepting the data in the read phase and applying decryption before passing it to MySQLi. - Describe a scenario where you would completely replace the physical file input with a dynamically generated dataset.
Importing CSV data generated on-the-fly from an API or another database without storing an intermediate file. - What are the potential security implications of using custom local infile handlers?
Mishandled input could lead to SQL injection or data corruption if data is not sanitized; also accessing unauthorized sources can expose sensitive data. - How can you debug issues when the LOAD DATA LOCAL INFILE command with a handler silently fails?
Enable error logging inside the handler, check MySQL server logs, verify local_infile settings, and test the handler callback independently. - Explain how you would optimize memory and performance when processing very large files using a local infile handler.
Use streaming with buffered reads/writes, avoid full file loads in memory, and close resources promptly after usage.
Frequently Asked Questions (FAQ)
Q1: What is the purpose of set_local_infile_handler() in PHP MySQLi?
A: It allows you to register a custom callback to handle LOAD DATA LOCAL INFILE commands, enabling data input from arbitrary sources rather than relying on local files.
Q2: Can I use set_local_infile_handler() with procedural MySQLi?
A: No, set_local_infile_handler() is only available with the MySQLi object-oriented interface.
Q3: What are the four commands the handler function must manage?
A: They are MYSQLI_LOCAL_INFILE_INIT, MYSQLI_LOCAL_INFILE_READ, MYSQLI_LOCAL_INFILE_END, and MYSQLI_LOCAL_INFILE_ERROR.
Q4: How do you enable local infile support in MySQL?
A: Make sure the MySQL server has local_infile=1 enabled and the client connection uses MYSQLI_OPT_LOCAL_INFILE option.
Q5: What if my handler returns an invalid resource?
A: The LOAD DATA query will fail and return an error because the MySQLi extension requires a valid stream for data input.
Conclusion
The mysqli::set_local_infile_handler() method offers PHP developers an advanced and flexible way to customize how data files are loaded into MySQL databases using the LOAD DATA LOCAL INFILE command. By implementing a callback handler, you can control data sources, apply preprocessing, and handle input dynamically without relying on physical files.
With attention to proper phase management, error handling, and resource management, you can leverage this feature to improve your application's data import workflows efficiently and securely.