How to Resolve Fatal Catchable Error While Trying to Show Messages

Asked

Viewed 300 times

8

I have a page where I check if the user has filled all the fields of a form but when trying to show the messages to the user the script returns me an error, I’m doing it this way:

class SendEmail
{
   private $nome;
   private $email;
   private $telefone;
   private $cidade;
   private $uf;
   private $assunto;
   private $mensagem;
   private $receive_mail;

   public function __construct($data)
   {

    $this->receive_mail = "[email protected]";
      try
      {
        if (count($data) sendMail();

      } catch (Exception $e) {
            return json_encode(array('success'=>'0','errors'=>$e->getMessage()));
      }    

     }

     public function sendMail()
     {
      $subject = $this->assunto;
      $body = "From {$this->nome}, \n\n{nl2br($this->mensagem)}";
      $headers = 'From: ' . $this->email . "\r\n" .
        'Reply-To: ' . $this->email . "\r\n" .
        'Content-type: text/html; charset=utf-8' . "\r\n" .
        'X-Mailer: PHP/' . phpversion();

       if (mail($this->receive_mail, $this->assunto, $body, $headers)) {
          return json_encode(array('success'=>'1','message'=>'Mensagem enviada com sucesso!'));
       } else {
          throw new Exception("Ocorreu um erro no envio da mensagem, por favor, tente mais tarde.");
       }
     }
}

if ($_POST) {
    // Aqui ele retornará um JSON com os erros ou a mensagem de sucesso
    echo json_encode(new SendMail($_POST)); 
}

And the whole message is this:

Catchable fatal error: Object of class SendEmail could not be converted to string in /home/anc/public_html/anc/sendEmail.php on line 84

The problem is I’m trying to show a Objeto as string from what I read in the php, but I couldn’t solve.

  • The email message should be accessible via the property or method of an object and not only by the constructor. print new SendEmail($_POST);

  • Could put the builder of this class?

  • I just edited the question with the full code.

2 answers

7


The problem of the line 84 is the print, trying to convert the object to string before printing it.

PHP objects cannot be converted to string unless they implement the magic method itself __toString.

Example:

class MyClass
{
    protected $minha_informacao = 'Informação importante';

     public function __toString()
     {
          return (string) $this->minha_informacao;
     }
}

You can convert them simply by doing so:

$obj = new MyClass;

echo $obj;

$string = (string) $obj;

If you want to see the values of an object, you should do what is described in the @rray response

I also saw that you want to convert an object to the format json. This in PHP is only possible using the function json_encode.

It is worth noting that in classes that do not implement the interface JsonSerializable this serialization to json does not occur in a desired way. The interface forces your class to contain the method jsonSerialize, who will "show" the function json_encode how that object will be serialized.

So do it like this:

class SendMail implements JsonSerializable
{
   public function jsonSerialize()
   {
       return $this->dados_que_quero_serializar;
   }
}

So it is possible to do:

 echo json_encode(new SendMail($_POST));

If you want to join the useful and pleasant to your object to be "printed" without having to change the shape you print, you can combine the two forms I taught you above:

class SendMail implements JsonSerializable

{
     public function jsonSerialize()
     {
          return array('email' => $this->email, 'nome' => $this->nome);
     }

     public function __toString()
     {
           return (string) json_encode($this);
     }
}

The way out of this will be:

echo new SendMail($_POST);

Exit:

 {"nome": "Wallace Maxters", "email" : "[email protected]"}
  • 1

    Hello, @Wallace Maxters, thanks for the great tips, solved my problem, thanks.

  • @adventistapr, your class will become "more beautiful" and yet broke learned a new interface, which is native to php

6

To display the structure of an array, object or other type other than a scalar use the functions, print_r() or var_dump().

The class constructor should not return anything beyond the object which is already done automatically, it makes no sense to return anything else. You call the creation of an object to manipulate and get a string. It’s like ordering a pizza at a restaurant and the waiter bringing a salad.

 public function __construct($data){
    $this->receive_mail = "[email protected]";
    try {
        if (count($data) sendMail();

    } catch (Exception $e) {
       //return estranho no construtor
       return json_encode(array('success'=>'0','errors'=>$e->getMessage()));
    }    
}

When calling this line you expect an email object or json?

//essa linha retorna um objeto ou json? o que esperar?
$email = new SendMail($_POST);
//a linha a baixo seria o mais adequado.
$json = json_encode($email->getMessage());

Simplified example of the problem:

class Email{
    private $message;

    public function __construct($msg){
        $this->message = $msg;
        return 'WTF? O.o';
    }

    public function getMessage(){
        return $this->getMessage();
    }
}

Example 1

$msg = 'Into the void';
$email = new Email($msg);
var_dump($email);

The exit will be:

object(Email)[1]
  private 'message' => string 'Into the void' (length=13)

A return in the constructor is never executed, just leaves the understanding method to it of strange. You called/asked to build an email object because it would receive something different?

From php5.4 it is possible to create an object and already invoke a method just by adding parentheses around the new class. The other solution is to create a new variable or call the return of the direct method in an ex function: json_econde().

Example 2, solution:

$msg = 'Into the void';
echo (new Email($msg))->getMessage();

Or else:

$msg = 'Into the void';
$email = new Email($msg);
echo json_encode($email->getMessage());

Exit:

Into the void

Browser other questions tagged

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