Wednesday, February 2, 2022

[SOLVED] Use cronjob to run function in php file

Issue

I have a function in my php file (file1.php). I am trying to use cronjob to call this function. My cron job command is:

php /home/name/public_html/file1.php mail1

For reference, the function code is below and works when called directly from the file (i.e., the issue does not appear to be with the function itself.

function mail1($runTotal, $accountArray){
    $to = $accountArray[0]['phoneNumber'] . '@vzwpix.com';
    $subject = '';
    $msg = "You have spent $" . $runTotal . " of $1,750 since the beginning of the month.;;
    $msg = wordwrap($msg);
    $headers = 'From: [email protected]';
    if (mail($to, $subject, $msg, $headers)) {
        echo $msg . " sent to " . $to;
    }
}

Am I calling the function in the wrong way?


Solution

Afraid to say that passing the name of the function you wish to call to the PHP script will not run the function within that script automatically. Your script file will need logic to respond to any command line arguments passed to it in order to execute correctly.

Let's say file1.php had several functions defined within it. Just a series of function definitions - no code outside of the functions. If you run that file on the command line ($ php file1.php), what will happen is PHP will load that file, parse your functions, but then since nothing in the file calls any of those functions, the script would reach the end, execution would complete, and nothing actually would have happened.

So in order to execute one of the functions, the script will need to inspect any command line arguments provided and then react appropriately.

In PHP, the $argv variable is an array that contains first the name of the file that was run, and then any command line arguments in order. Unless enclosed in quotes or escaped properly, white space serves as the separators for command line arguments. If the command was run through the command line, this variable is available to you in the root scope*.

Here's PHP's description of the $argv variable:

Contains an array of all the arguments passed to the script when running from the command line.

Note: The first argument $argv[0] is always the name that was used to run the script.

If you run php file1.php send mail --dry-run, then the $argv variable would be (shown here in JSON): ["file1.php", "send", "mail", "--dry-run"].

What you can do with this is place at the end of your file1.php file code that looks at that $argv variable and takes an appropriate action. In the specific case outlined in your question, try adding something like this to the end of your file:

//If we have a command line argument
if (!empty($argv[1])) {
    switch ($argv[1]) {
        case "mail1":
            mail1(); //Call our mail() function
            echo "\n\nCalled function mail1()\n\n"; //Print what we did to the console
            break;
    }
}

Now when you fun php file1.php mail1, which is ultimately what your CRON job is doing, that first argument ($argv[1]) is "mail1", so the mail1 case in the switch statement is executed, which calls your mail1 function and writes to the console a helpful note so you know it did what you asked.

Useful links:

Hope this helps!

* By root scope I mean that it is not global, so you can't access it inside a function or a class unless you pass it along to them, but outside of them you have access to it. In my code example above, since that code is outside of a function or a class, it can access $argv.



Answered By - stratedge
Answer Checked By - Mary Flores (WPSolving Volunteer)