0

There is a good chance that this has been asked before, but I can't find an answer that works in my situation. I'm a hobby programmer, not a professional developer:-)

I have a client side script running under WordPress (which I don't think is relevant to the problem) that has JavaScript code to perform an ajax call to a server side PHP script (Add_CDB_Record.php). Within Add_CDB_Record.php I have a "require_once" that pulls in another PHP script (include_headers.php) from the same server.

The issue I am battling with is that the code immediately after the "require_once" line in Add_CDB_Record.php is executed BEFORE the include_headers.php script is actually executed.

Worse still, the code in include_headers.php is then executed later (after the remainder of Add_CDB_Record.php has done it's job) and seems to restart the code from the after the require_once (almost like a callback).

A log entry at the start of my include_headers.php is displayed when the require_once is first started, and again a short while afterwards when it is actually executed. I tried putting a sleep(10) after the require_once and that had no effect (other than slowing the script by 10 seconds of course!)

My server currently uses PHP8.0.28. [Corrected the PHP version]

My understanding is that PHP is synchronous by default (meaning that each statement has to finish before the next statement executes, and when the last statement in the script executes the script is returned to the calling script). So my expectation is that the "require_once" would import the include_headers.php file and then execute it before moving on to the remainder of the Add_CDB_Record.php script.

Code examples below are extracts and tidied up to simplify understanding (I hope!).

Thank you for your assistance.

HTML (Client side)

        $.ajax({
            url: '../wp-content/themes/u-design-child/CDB/Add_CDB_Record.php',
            type: 'POST',
            datatype: 'json',
            timeout: 10000,
            data: createDataset()   
        })
        .fail(function (jqXHR, textStatus, errorThrown){
            errorintro = 'Ajax Step 1 Add CDB Record failed:';
            displayTxt = $.OnXHRError(jqXHR, textStatus, errorThrown)
            alert('We are sorry, an error has occurred.');
            clear_submit_button(); 
            $.stopSpinner();
            return false;
        })  // End of request.fail callback handler             
        .done (function(databack, textStatus, xhr) {
            if(databack.includes("Mail Sent")) { 
                alert ("Thank you. Your details have been received and an email confirmation sent to your email address (if provided).");
                resetForm(); //Reload the page
                return true; 
            } else {
                alert('ERROR: Your Client record has not been created.\nError: ' + response);
                return false;
            }
        }); // End of request.done callback handler 

Extract from Add_CDB_Record.php (server side)

    require_once(get_theme_root() . 'include_headers.php');

    $AuthResponse = authenticate_access();
    
    //...remaining code here

Extract from include_headers.php (server side)

    // provides standard headers, authentication tests, error handling and php utilities
    // including....
    
    function authenticate_access() {
        $GLOBALS['$clientcaller'] = 'undeclared';
        $clientcaller = $GLOBALS['$clientcaller'];
        if(isset($_REQUEST['authentic'])) {
            $GLOBALS['$clientcaller'] = $_REQUEST['authentic'];
            $clientcaller = $GLOBALS['$clientcaller'];
        }
        
// Check current_user to prove logged in as WP or PubLic for genuine public forms
    if (isset($_REQUEST['current_user'])) {
        if ($_REQUEST['current_user'] !== 'PubLic') {
            if(empty($_REQUEST['current_user'])) {
                elog('current_user false - immediate exit.');
                header('HTTP/1.1 500 Internal Server Error');
                header('Content-Type: application/json; charset=UTF-8');
                die(safe_json_encode(array('[Error]: ' . $_REQUEST['authentic'] .  ' Authenticate_access - Unauthorised Access Procedure Call (U1)')));
                exit; //exit if not true
            };
        } else {
            elog('current_user empty:' . $_REQUEST['current_user']);
            header('HTTP/1.1 500 Internal Server Error');
            header('Content-Type: application/json; charset=UTF-8');
            die(safe_json_encode(array('[Error]: Authenticate_access - Unauthorised Access Procedure Call (U4)')));
            exit; //exit if authentic not set
        }
    };
// All genuine calls to this procedure must have authentic=true to continue
    if (isset($_REQUEST['authentic'])) {
        if(!empty($_REQUEST['authentic'])) {
            if ($_REQUEST['authentic'] == 'No') {
                elog('Authentic false - immediate exit');
                header('HTTP/1.1 500 Internal Server Error');
                header('Content-Type: application/json; charset=UTF-8');
                die(safe_json_encode(array('[Error]: ' . $_REQUEST['authentic'] .  ' Authenticate_access - Unauthorised Access Procedure Call (A3)')));
                exit; //exit if not true
            };
        } else {
            elog('Authentic empty:' . $_REQUEST['authentic']);
            header('HTTP/1.1 500 Internal Server Error');
            header('Content-Type: application/json; charset=UTF-8');
            die(safe_json_encode(array('[Error]: Authenticate_access - Unauthorised Access Procedure Call (A4)')));
            exit; //exit if authentic not set
        }
        return true; 
    };
    //Fall through all checks - catch in case
    elog('Authentic missing (all checks)');
    header('HTTP/1.1 500 Internal Server Error');
    header('Content-Type: application/json; charset=UTF-8');
    die(safe_json_encode(array('[Error]: Authenticate_access - Unauthorised Access Procedure Call (A5)')));
    exit; 
    //exit if authentic doesn't exist 
    

    $erroroccurred = false;
    //error handler function
    function customError($errno,$errstr,$errfile,$errline,$errcontext) {
        echo "<b>Error:</b> ($errline) [$errno] $errstr in $errfile<br />$errcontext<br />";
        elog ("Error: " . "(" . $errline . ")" . "[" . $errno . "]"  . $errstr . " in " . $errfile . "|" . $errcontext );
        global $erroroccurred;
        $erroroccurred = true;
    }
    
    //set error handler
    set_error_handler("customError",E_ALL);
    return;
}//end authenticate_access function
SteveParry
  • 117
  • 1
  • 1
  • 10
  • 8
    It won't ever execute out of order like that. Ever. Something is calling something twice, and/or some kind of loop could be happening. It's not immediately apparent from the code here. Keep digging. – ADyson Jun 08 '23 at 06:25
  • Targettng script files that are located somewhere in your theme or plugin folder directly is rather ugly, btw. - there is a _proper_ way to "do AJAX" in WP, https://developer.wordpress.org/plugins/javascript/ajax/ – CBroe Jun 08 '23 at 06:48
  • 1
    As far as I can tell, `include_headers.php` contains one function definition, `authenticate_access()`, and that's it (no calls). Then `Add_CDB_Record.php` calls the `authenticate_access()` function defined in `include_headers.php`. Can you please add to your `include_headers.php` the log entry you mention, so we can see how that was setup? Depending on its position, a log entry is expected when the file is included, and then separate log entries when the function actually runs. – Caleb Jun 08 '23 at 12:50
  • Thanks everyone. After several hours with multiple error_log comments I made no progress on finding out why the authenticate_access() function was being run twice. Add_CDB_Record.php was definitely only called once and there was only one call in Add_CDB_Record.php to authenticate_access() and one require_once for the include_headers.php. I gave up in the end and did it a completely different way. – SteveParry Jun 09 '23 at 06:32
  • @CBroe - Sorry - I didn't understand what that link was telling me. For context, this isn't a plug-in. The php is a wordpress template attached to a page, which then calls Add_CDB_Record.php via ajax. – SteveParry Jun 09 '23 at 06:36
  • What should I do now? delete this post altogether, or mark it closed (how?)? Thx again! – SteveParry Jun 09 '23 at 06:37
  • 1
    We don't mark threads as closed here, you can only accept a given answer - real answer, not just a discussion in the comments. You can write a self-answer, if you figured out what the problem was - https://stackoverflow.com/help/self-answer – CBroe Jun 09 '23 at 06:40
  • _"For context, this isn't a plug-in."_ - that doesn't matter too much, you can still use these methods to set this up properly from within the functions.php of your theme. – CBroe Jun 09 '23 at 06:41

0 Answers0