Jeramy
Jeramy

Reputation: 470

PHP variable scope issue in class extending SOAP

I am working on a way to verify account numbers. The $account_number is passed in from another function for verification. I ran into a scoping issue for my variables, passing from function to class. I have it working, but I resorted to using $GLOBALS to get around the scoping issue. I feel like there must be a better way. Here is what I have:

$acct;
$subAcct;
$chart;
$object;
$subObject;
$project;

function verifyACCT($account_number){
    //Strip all but numbers and letters, truncate to first seven digits, and convert to uppercase
    $account_number = strtoupper(preg_replace("/[^a-z0-9]/i", "", $account_number));
    $GLOBALS['$acct'] = substr($account_number, 0, 7);
    $GLOBALS['$subAcct'] = substr($account_number, 8);
    $GLOBALS['$chart'] = "XX";
    $GLOBALS['$object'] = "0000";
    $GLOBALS['$subObject'] = null;
    $GLOBALS['$project'] = null;

    class ACCTSoapClient extends SoapClient {

        public function __doRequest($request, $location, $action, $version, $one_way=0) {

            $request = '<?xml version="1.0" encoding="utf-8"?>
            <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <soap:Body>
            <isValidAccountString xmlns="http://URL/">
            <chartOfAccountsCode xmlns="">'.$GLOBALS['$chart'].'</chartOfAccountsCode>
            <accountNumber xmlns="">'.$GLOBALS['$acct'].'</accountNumber>
            <subAccountNumber xmlns="">'.$GLOBALS['$subAcct'].'</subAccountNumber>
            <objectCode xmlns="">'.$GLOBALS['$object'].'</objectCode>
            <subObjectCode xmlns="">'.$GLOBALS['$subObject'].'</subObjectCode>
            <projectCode xmlns="">'.$GLOBALS['$project'].'</projectCode>
            </isValidAccountString>
            </soap:Body>
            </soap:Envelope>';

            return parent::__doRequest($request, $location, $action, $version, $one_way);
        }
    }

    $client = new ACCTSoapClient("https://URL?wsdl", array("connection_timeout"=>5, 'exceptions' => 0));

    try {
        $result = $client->isValidAccountString(null);
        return ($result->return); //boolean (1 for valid, null for invalid)
    } catch(SoapFault $e) {
        echo 1;
    } catch(Exception $e) {
        echo 1;
    }
}

Upvotes: 0

Views: 65

Answers (1)

ST2OD
ST2OD

Reputation: 725

In order to get around using $_GLOBALS (which is considered very bad practice) you need to refactor your code.

You are currently mixing a procedural code approach with object-oriented programming.

  1. Separate the class ACCTSoapClient and create a new class for your verification.
  2. Use dependency injection to set the SoapClient class in the verification class. Or for simplicity just instantiate it in the constructor.
  3. Place your currently global variables inside the new verification class with an access-modifier protected or private.
  4. Create a public function verify inside the verification class
  5. Now instantiate the verification class and call the verify method
  6. The verify method will call the doRequest method of your SOAP class and return the response

I hope this helps you to bring you on the right track.

Upvotes: 1

Related Questions