PHP: Dynamic method calling

Erland Muchasaj
4 min readApr 16, 2024

--

A comprehensive guide on how to write dynamic method calling in php.

Dynamic method calling in PHP

PHP offers powerful features like dynamic method calling, enabling developers to create flexible and efficient solutions. In this article, we’ll explore how dynamic method calling can be utilized in PHP to import CSV data from various sources with ease and efficiency.

To give a little bit of context. A few years ago I had to scrap some sites for data into CSV formatted files, and then use those files to import the data to a management system.

Of course, the data was coming from different sources (like 4/5 different ones). I was in charge of building a script that handled these use cases.

Below is the format of 2 different files:

Data from boats-specs.com

The second file is this:

List of data from boats.csv

Definition

Dynamic method calls refer to calling a method on an object using a variable containing the method name.

Pros

  1. Flexibility: Allows for greater flexibility in method invocation, especially in scenarios where the method name isn’t known beforehand.
  2. Reduced Repetition: It can help reduce code repetition by dynamically invoking methods based on variables.

Cons

  1. Readability: Overuse of dynamic method calls can make code harder to read and understand, as it’s not immediately clear which methods are being called.
  2. Debugging: Debugging code with dynamic method calls can be more challenging because errors may not be caught until runtime.

Usage

A basic example of how a dynamic method is called in PHP, as stated in the definition above, is through a variable.

<?php 

class Importer
{
public function import() {
echo "importing...";
}
}

$methodName = "import"; // or can be dynamiclly created
$obj = new Importer();
$obj->$methodName(); // This will call the import() method

# Output
importing...

Considering the example above, the dynamic method does not do much, but imagine you have different file formats (as in the files above) that need to be imported. What we can do is create a separate function that handles import per each file type and also a generic method that will call a specific function based on the file.

I know seems much but let’s see it in practice.

<?php 

class Importer
{
/**
* Import data from a specific CSV source

* @param string $path path of file
* @param string $delimiter of CSV file
*
* @return void
* @throws UnableToProcessCsv
*/
public static function import(string $path, string $delimiter = ","): void
{
try {
// Open the CSV file for reading
$csvFile = fopen($path, 'r');

// if we do not have access to read the file we return
if ($csvFile === false) {
throw new UnableToProcessCsv("Unable to open CSV file: $path");
}

// Read and store the header row
$header = fgetcsv($csvFile, null, $delimiter);

// Initialize an empty array to store current data
$data = [];

// Process the CSV file in chunks
while (!feof($csvFile)) {
// Read row from the CSV file
$row = fgetcsv($csvFile, null, $delimiter);
if ($row !== false) {
// Skip processing if it's the header row
if ($row !== $header) {
// we save data as key => value pare
$data[] = array_combine($header, $row);
}
}
}

// Close the CSV file
fclose($csvFile);

if (! empty($data)) {
// Determine wwhere the data is comming from, based on URL:
$parse = parse_url($data[0]['url']);

$url = preg_replace('/^www\./i', '', $parse['host']);

$url = str_replace('.', '_', $url);

$value = ucwords(str_replace(['-', '_'], ' ', $url));

// we create a method like: handleDomainName and we then call it dynamically
$method = 'handle' . str_replace(' ', '', $value);

// Always check if method exists before calling
if (method_exists(__CLASS__, $method) && is_callable([__CLASS__, $method], true, $callable_name)) {
// Process the chunk data (e.g., insert into database)
$callable_name($data);
}
}

// Free memory by clearing the chunk data
$data = [];
} catch (Exception $e) {
// Handle any exceptions thrown during CSV processing
// Log the error or throw a custom exception
echo $e->getMessage();
}
}

/**
* Handle boat-specs.com Import.
*
* @param array $records The records to process.
*
* @return void
*/
protected static function handleBoatSpecsCom($records): void
{
foreach ($records as $key => $record) {
// process each record and save into database
}
}

/**
* Handle boats.com Import.
*
* @param array $records The records to process.
*
* @return void
*/
protected static function handleBoatsCom($records): void
{
foreach ($records as $key => $record) {
// process each record and save into database
}
}
}

Importer::import('boats.csv'); // This will call the import() method

Above we created an entry-point import() where we pass the file that we are processing. Then the script based on URL of the record determines which method to call handleDomainName and each method processes the file separately.

Always when using dynamic method calling consider these practices:

  1. Always check if method/function exists using: method_exists(object|string $object_or_class, string $method) or function_exists(string $function)
  2. When incorporating user input to call dynamic methods in your code, it’s crucial to prioritize security by sanitizing the input. This step helps prevent potential security vulnerabilities such as injection attacks. Always sanitize user input before utilizing it to invoke dynamic methods, ensuring a robust and secure application.

In the context of CSV data import, dynamic method calling enables developers to handle data from different sources with ease and precision. By leveraging this feature, developers can create robust and adaptable applications capable of processing diverse data sets effectively.

Feel free to Subscribe for more content like this 🔔, clap 👏🏻 , comment 💬, and share the article with anyone you’d like

And as it always has been, I appreciate your support, and thanks for reading.

--

--