3

I have this code :

public function changeProfile ($first_name, $last_name, $email, $phone, $password, 
                             $bank_name, $bank_account_number, $bank_account_name, 
                             $gender, $birthday, $address, $area, $default_type) {

    $this->connect();

    $data = array ('first_name' => $this->escapeString($first_name),
                   'last_name' => $this->escapeString($last_name),
                   'email' => $this->escapeString($email),
                   'phone' => $this->escapeString($phone),
                   'password' => $this->escapeString($password), 
                   'bank_name' => $this->escapeString($bank_name),
                   'bank_account_number' => $this->escapeString($bank_account_number),
                   'bank_account_name' => $this->escapeString($bank_account_name),
                   'gender' => $this->escapeString($gender),
                   'birthday' => $this->escapeString($birthday),
                   'address' => $this->escapeString($address),
                   'area' => $this->escapeString($area),
                   'default_type' => $this->escapeString($default_type));

    $this->update('user', $data, 'email = "'.$email.'" AND phone = "'.$phone.'"');
    $res = $this->getResult();      

}

Now, I have a problem like this :

I want to 'skip' some variables on the function, for example $birthday and $gender, so that it won't be processed on SQL UPDATE and let the current data as it is.

I mean, if $birthday and $gender data doesn't exist, then don't update existing data on the table. because when I tried to use NULL as variables on the function, my data replaced with empty data.

how to manage this situation without having multiple if to check each variables?

thank you

4
  • 2
    You could pass in an array instead of an exponentially increasing list of arguments, then loop through the array and construct your query/arguments to pass to $this->update() Commented Jan 19, 2016 at 4:18
  • @RobbieAverill : nice thoughts... Commented Jan 19, 2016 at 4:22
  • 1
    It's kind of hard to work around it with the current structure... func_get_args() comes to mind although you wouldn't be able to determine which field is which. Commented Jan 19, 2016 at 4:23
  • 2
    @RobbieAverill, you could use ReflectionMethod instead or you could use an array of keys matching your parameters (see answer below). But I don't particular like that approach. Commented Jan 19, 2016 at 4:52

3 Answers 3

3

If you have the option, you should replace your function's argument list with an array of arguments, for example:

public function changeProfile($variables)
{
    $this->connect();

    $data = array();
    foreach ($variables as $key => $value) {
        $data[$key] = $this->escapeString($value);
    }

    // Validation?
    if (!isset($data['email'], $data['phone'])) {
        die('Required fields missing.');
    }

    $this->update('user', $data, 'email = "' . $data['email'] . '" AND phone = "' . $data['phone'] . '"');
    $res = $this->getResult();
}

This assumes that the SQL query is static. You could also add some more fields to it if you needed to.

You'd then call it like this:

$test->changeProfileUpdated([
    'first_name' => 'john',
    'last_name' => 'doe',
    'email' => '[email protected]',
    'phone' => 12345,
    'password' => 'password1',
    'bank_name' => 'ANZ',
    'bank_account_number' => '123-456',
    'bank_account_name' => 'J DOE',
    'gender' => 'M',
    'birthday' => '1/2/13',
    'address' => '12 Fake St',
    'area' => 'Area 51',
    'default_type' => 'Some default'
]);

Here's a demo comparing your code, this example and a validation failure.

Sign up to request clarification or add additional context in comments.

Comments

3

If you cannot change the method signature to take an array instead you can naturally check each value with isset() or empty() depending on your data needs like:

if (!empty($gender) {
    $data['gender'] => $this->escapeString(escapeString);
}

However this is tedious. A better way would be to take an array as an input and then have an array of valid and or required keys. Something like this:

class MyClass
{
    private $valid_keys = [
        "first_name", "last_name", "email", "phone", "password", 
        "bank_name", "bank_account_number", "bank_account_name", 
        "gender", "birthday", "address", "area", "default_type"
    ];

    public function changeProfile($profile)
    {
        // Return valid keys
        $profile = array_filter($profile, function ($key) {
            return in_array($key, self::$valid_keys);
        } , ARRAY_FILTER_USE_KEY);

        // Escape values
        $profile = array_map(function ($value) {
            // .. your escape function
        }, $profile);

        // Do your stuff
        $this->update('user', $profile, 'email = "'. $profile['email'].'" AND phone = "'.$profile['phone'].'"');
        $res = $this->getResult();      
    }
}

That way you'll only set valid data and you have a way of escaping it generically.

Oh yeah and of course only the values in $profile will get send to your update function.

If you cannot change the method signature you can look into using func_get_args().

public function changeProfile($first_name, $last_name, $email, $phone, $password, 
                         $bank_name, $bank_account_number, $bank_account_name, 
                         $gender, $birthday, $address, $area, $default_type)
{
    $args = func_get_args();

    $profile = [];
    // Important: $valid_keys should be the same as your function parameters and in the same order for this to work. If you want to go further you can look at `ReflectionMethod` to get the names through reflection.
    foreach ($args as $index => $value) {
        $key = self::$valid_keys[$index];
        $profile[$key] = $this->escapeValue($value);
    }

    // Do your stuff
    $this->update('user', $profile, 'email = "'. $profile['email'].'" AND phone = "'.$profile['phone'].'"');
    $res = $this->getResult();
}

Comments

1

check if it is null or not then save it in an array as given below

function changeProfile ($first_name, $last_name,$email,$phone) {
   $this->connect();
 $data=array();
 if($first_name!=""){
     $data['first_name']= $this->escapeString($first_name);
 }
  if($last_name!=""){
     $data['last_name']=$this->escapeString($last_name);
 }
if($email!=""){
     $data['email']=$this->escapeString($email);
 }
if($phone!=""){
     $data['phone']=$this->escapeString($phone);
 }
    $this->update('user', $data, 'email = "'.$email.'" AND phone = "'.$phone.'"');
    $res = $this->getResult();


}

1 Comment

The problem with this approach is that you have a lot of repetition in your code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.