Variable is not updated in constructor

4

I'm learning OO and venturing into PHP, but I've come across something I believe in theory should work, but in practice it does not.

<?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;
  }
}

Then 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 is called type hinting something so I believe.

I'm saying here that I want to $nome only accept the string type:

$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 in the parameters of the function.

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

But when I do this it does not work and it is returning a bug in the console, am I doing something wrong?

    
asked by anonymous 30.08.2016 / 23:04

3 answers

10

It is a very simple error, but at the same time, chatinho to notice, and is here

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

You are calling the method

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

And this method returns nothing (null).

Only you get this null and save it in $this->senha soon after:

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

That is, you just overwritten what setPassword created.

Correct would take away the assignment, and let the method work alone:

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 at IDEONE .

Type Hinting , how you used the tag "> php7 , that is to say that they are Type Declarations , but unfortunately they are not so suitable to help in your case, as they work in a specific way.

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

More details in the manual:

  

link

Another thing: $a = ( tipo ) $b; is casts , has no relation to Type Declaration or Hinting . In your case, they will not prevent you from using wrong values.

More details in the manual:

  

link

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

Something like this:

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;
  }

How to use:

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

I made some minor changes. The error is because it is calling the method in the wrong way, it returns nothing so it can not assign to a variable. If you want it to run, just call it.

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);

See run on ideone

I took the casts . They will only bring problems, he does not 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 make sure that the parameter types are the way you want it, you will have to use if itself. Or in PHP 7 use the type hinting as tried (but not all types can be used yet, so the error). See:

30.08.2016 / 23:12
3

The initial problem is that you double-set the password property as already said in other Answers .

As you are beginning, I would like to complement some of the good practice points.

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

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

In a file where only code exists, prefer to use {}

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

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

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

Finally, you'd prefer to fire a Exception instead of die and quit your whole script.

See some references to Exceptions :

Finally, if code can get to look like this:

// 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();
}
    
30.08.2016 / 23:50