Variable is not updated in constructor

Asked

Viewed 148 times

5

I’m learning OO and venturing into PHP, only I came across something that I think in theory should work, but in practice does not work.

<?php 

class Users{

  public $name; 
  public $idade;
  public $email;
  private $senha;

  function __construct($name, $idade, $email, $senha){
    $this->name = (string) $name;
    $this->idade = (int) $idade;
    $this->email = (string) $email;
    $this->senha = $this->setPassword($senha);
    echo "O objeto foi contruido!";

  }

  function setPassword($senha){
    if (strlen($senha) > 8 and strlen($senha) < 13):
        $this->senha = password_hash($senha, PASSWORD_DEFAULT);
    else:
        die ('Sua senha deve conter entre 8 e 13 caracters');
    endif;
  }
}

There when I use :

$pessoa = new Users("Flavio", 19, "[email protected]", "testando123");
var_dump($pessoa);

He printa :

O objeto foi contruido!
C:\wamp\www\ws_php\n.php:6:
object(Users)[1]
  public 'name' => string 'Flavio' (length=6)
  public 'idade' => int 19
  public 'email' => string '[email protected]' (length=22)
  private 'senha' => null

the password becomes null.

but when I try :

$pessoa->setPassword("testando123");

it works normally.

Where am I going wrong?

One more question I have is about something I saw that’s called hinting type something like this I believe.

I’m saying here I want $nome only accept the type string:

$this->name = (string) $name; // AQUI
$this->idade = (int) $idade;
$this->email = (string) $email;
$this->senha = $this->setPassword($senha);

but I saw that in PHP 7 it is possible to pass the function parameters.

function __construct(string $name, int $idade, string $email, $senha)

But when I do this does not work and me is returning an error on the console, I am doing something wrong?

  • Codestyle question: it is more common to use {} instead of : in ifs and the like.

3 answers

12


It’s a very simple mistake, but at the same time, boring to notice, and it’s here

$this->senha = $this->setPassword($senha);

You are calling the method

$this->senha = $this->setPassword($senha);
               ^^^^^^^^^^^^^^^^^^^^^^^^^^

And this method returns nothing (null).

Only you take this null and keep it in $this->senha right away:

$this->senha =  $this->setPassword($senha);
^^^^^^^^^^^^^^

I mean, you just wrote what the setPassword created.

The correct thing would be to take the assignment, and let the method work on its own:

function __construct($name, $idade, $email, $senha){
    $this->name = (string) $name;
    $this->idade = (int) $idade;
    $this->email = (string) $email;
    $this->setPassword($senha);
    echo "O objeto foi contruido!";
}

See working on IDEONE.

About the Type Hinting, how did you use the tag , is worth saying that now are Type Declarations, but unfortunately they are not as suitable to help in your case, as they work in a somewhat specific way.

When you declare in the function, for example a bool, the function will expect a "bool instance", and not the primitive type.

More details in the manual:

http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration

Something else: $a = ( tipo ) $b; sane Casts, has nothing to do with Type Declaration nor Hinting. In your case, they will not prevent the person from using wrong values.

More details in the manual:

http://php.net/manual/en/language.types.type-juggling.php

Finally, instead of the die(); would suggest you create a flag in your code to tell whether the object is valid or not.

Something like that:

class Users{
  public $name; 
  public $idade;
  public $email;
  public $isValid;
  private $senha;

  function __construct($name, $idade, $email, $senha){
    $this->name = $name;
    $this->idade = $idade;
    $this->email = $email;
    $this->isValid = $this->setPassword($senha);
  }

  function setPassword($senha){
    if (strlen($senha) > 8 and strlen($senha) < 13) {
      $this->senha = password_hash($senha, PASSWORD_DEFAULT);
      return true;
  } else {
      $this->senha = '';
      return false;
  }

  function isValid(){
    return $this->isValid;
  }

Mode of use:

$pessoa = new Users( 'Flavio', 19, '[email protected]', 'testando123' );
if( $pessoa->isValid() ) {
    // faz o que tem que fazer
else {
    // avisa que deu problema
}

6

I made a few minor changes. The error is because it is calling the method wrong, it returns nothing, so it cannot assign to a variable. If you want him to perform, just call him.

class Users {
    public $name; 
    public $idade;
    public $email;
    private $senha;
    function __construct($name, $idade, $email, $senha){ 
        $this->name = $name;
        $this->idade = $idade;
        $this->email = $email;
        $this->setPassword($senha);
        echo "O objeto foi contruido!";
    }
    function setPassword($senha) {
        if (strlen($senha) > 8 and strlen($senha) < 13) {
            $this->senha = password_hash($senha, PASSWORD_DEFAULT);
        } else {
            die ('Sua senha deve conter entre 8 e 13 caracters');
        }
    }
}
$pessoa = new Users("Flavio", 19, "[email protected]", "testando123");
var_dump($pessoa);
$pessoa->setPassword("testando123");
var_dump($pessoa);

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

I took the Casts. They’ll only bring trouble, he doesn’t do what he imagines. Cast is to convert one data to another. If it works great, if it fails you will not have valid information.

If you want to ensure that the parameter types are the way you want to use if same. Or in PHP 7 use hinting type, as tried (but not all types can be used yet, so the error). See:

3

The initial problem is that you set the property twice password as already said in others answers.

As you are starting out, I would like to complement with some legal points of good practice.

The first is the use of : in the if and in other structures. Although it works, the focus of : is for use in templates:

<?php if ($var instanceof Legume): ?>
    Pode ser uma batata!
<?php else: ?>
    Não é uma batata
<?php endif; ?>

In a file where there is only code, prefer to use the {}

if ($var instanceof Legume) {
    Pode ser uma batata!
} else {
    Não é uma batata
}

Another point is the visibility of methods. PHP uses function to define the methods and it is not mandatory to define the visibility. If nothing is defined the method is treated as public. This behavior comes from PHP 4, and nowadays, it’s better to make it explicit that something is public.

To get a better idea of how to write code, you can rely on the code style PSR-2. This is the standard adopted by several PHP projects and this ensures that the written code is visually similar, regardless of who wrote the code.

Finally, you’d rather fire one Exception instead of making a die and terminate your entire script.

See some references about Exceptions:

Finally, if code can get that way:

// Arquivo Users.php
class Users 
{
    public $name; 
    public $idade;
    public $email;
    private $senha;

    public function __construct($name, $idade, $email, $senha){ 
        $this->name = $name;
        $this->idade = $idade;
        $this->email = $email;
        $this->setPassword($senha);
        echo "O objeto foi contruido!";
    }

    public function setPassword($senha) {
        if (strlen($senha) > 8 and strlen($senha) < 13) {
            $this->senha = password_hash($senha, PASSWORD_DEFAULT);
        } else {
            throw new InvalidArgumentException(
                'Sua senha deve conter entre 8 e 13 caracteres'
            );
        }
    }
}

// Arquivo index.php
try {
    $pessoa = new Users("Flavio", 19, "[email protected]", "testando123");
    var_dump($pessoa);

    // Aqui vai dar erro
    $pessoa->setPassword("ba");
    var_dump($pessoa);

catch (InvalidArgumentException $e) {
    // Faz alguma magia negra.

    echo $e->getMessage();
}
  • 1

    Thank you very much!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.