Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) Método __construct() não é executado


Rafael Laurindo

Pergunta

Galera, o método __construct() não é executado no seguinte caso:

<?php
class Pessoa{
public __construct(){
echo 'OK!';
}
}

<?php
require_once 'Pessoa.php';
class GenPessoa extends Pessoa{
public print_var_dump($obj){
echo var_dump($obj);
}
}
new GenPessoa();

Esse código deveria retornar: OK!

Eu achava que ao usar o extends o método __construct() da classe Pessoa seria executado automaticamente, mas isso não acontece, alguém sabe me dizer por quê?

Editado por Rafael Laurindo
Link para o comentário
Compartilhar em outros sites

17 respostass a esta questão

Posts Recomendados

  • 0

Cade o parametro que diz que é função? desse jeito da erro dentro do proprio PHP bem executa ... você só esta dando os nomes sem dizer o que é ...

<?php
class Pessoa {
 public function __construct() {
  echo 'OK!';
 }
}

class GenPessoa extends Pessoa {
 public function print_var_dump($obj) {
  echo var_dump($obj);
 }
}

// Imrpime: OK! string(5) "Teste"
$classe = new GenPessoa();
$classe->print_var_dump("Teste");
?>

Editado por SK15
Link para o comentário
Compartilhar em outros sites

  • 0

Salve,

Diferente de outras linaguens de programação, o PHP não invoca o construtor pai ao criar uma instancia de uma classe filho.

Se você deseja que o construtor pai seja executado toda vez que uma instancia da classe filha seja criada, você deve elaborar um código semelhante a este:

<?php

class Pai{
    public function __construct(){
        printf('<h1>Construtor do pai invocado</h1>');
    }
}

class Filho extends Pai{
    public function __construct(){
        // invocando o construtor pai
        parent::__construct();
    }
}

// Exemplo de uso
$objetoFilho = new Filho();

?>
Espero que posse lhe ajudar Abraços
Galera, o método __construct() não é executado no seguinte caso:
<?php
class Pessoa{
public function __construct(){
echo 'OK!';
}
}

<?php
require_once 'Pessoa.php';
class GenPessoa extends Pessoa{
public function print_var_dump($obj){
echo var_dump($obj);
}
}
new GenPessoa();

Esse código deveria retornar: OK!

Eu achava que ao usar o extends o método __construct() da classe Pessoa seria executado automaticamente, mas isso não acontece, alguém sabe me dizer por quê?

Editado por ursolouco
Link para o comentário
Compartilhar em outros sites

  • 0

Salve,

Entendi perfeitamente, muito obrigado amigo. A diferença está no "parent", ele faz referência a uma classe superior certo?

A palavra chave "parent" esta referenciando as informações da classe Pai (literalmente), esta correto seu raciocinio.

Não funcionou. O método __construct() da classe Pai não devia ser "static" não.

Não tem nada a ver o metodo se estatico ou não!!

Pode seu código original para a galera dar uma olhada.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

olhem o código...

<?php

require_once 'Main.php';

[indent]class Sample_Pessoa{[/indent]
    private function obterAluno(){ //pega os dados do aluno depois de submetido pelo formulário
        $this->sobreNome = $_POST['txtSobreNome']; //a superglobal $_POST recebe o value (valor) do form
    }

    private function adicionarAluno(){
        $this->obterAluno();        
        $this->_db->_conn->beginTransaction(); //inicia uma transação. O _db pertence a classe Pessoa. O this deve ser usado em caso de herança
        $this->adicionarPessoa();
        if (empty($this->id)){
              $this->_db->_conn->rollback(); //rola para traz e deixa o banco exatamente como antes do início da transação, se qualquer coisa falhar numa transação
        }        
        $add = "
            insert into genPessoa(id_pessoa, sobreNome)
            values (?, ?)
        ";        
        $stmt = $this->_db->_conn->prepare($add);        
        $stmt->bindParam(1, $this->id, PDO::PARAM_INT);        
        $stmt->bindParam(2, $this->sobreNome, PDO::PARAM_STR);
        if (!$stmt->execute()){
            $this->_db->_conn->rollback();
        }        
        $this->_db->_conn->commit(); //encerra a transação        
        
        $bio = new BIO();
        $bio->msgBox('Cadastro efetuado com sucesso!');        
        $bio->redirectTo('/sample/sample.php');
    }
}
<?php

require_once 'Main.php';

class Sample_Aluno extends Sample_Pessoa{    
    public $sobreNome;

    public function __construct(){
        //$this->_db = new Sample_Main();
        //chama o método construct da classe pai
        parent::__construct();
        //verifica se o botão clicado é o de adição
        /*if($_POST['btnSalvar'] != NULL)
            $this->adicionarAluno();/**/
        //o value do botão deve mudar de nome em dados editados        
    }

    private function obterAluno(){ //pega os dados do aluno depois de submetido pelo formulário
        $this->sobreNome = $_POST['txtSobreNome']; //a superglobal $_POST recebe o value (valor) do form
    }

    private function adicionarAluno(){
        $this->obterAluno();        
        $this->_db->_conn->beginTransaction(); //inicia uma transação. O _db pertence a classe Pessoa. O this deve ser usado em caso de herança
        $this->adicionarPessoa();
        if (empty($this->id)){
              $this->_db->_conn->rollback(); //rola para traz e deixa o banco exatamente como antes do início da transação, se qualquer coisa falhar numa transação
        }        
        $add = "
            insert into genPessoa(id_pessoa, sobreNome)
            values (?, ?)
        ";        
        $stmt = $this->_db->_conn->prepare($add);        
        $stmt->bindParam(1, $this->id, PDO::PARAM_INT);        
        $stmt->bindParam(2, $this->sobreNome, PDO::PARAM_STR);
        if (!$stmt->execute()){
            $this->_db->_conn->rollback();
        }        
        $this->_db->_conn->commit(); //encerra a transação        
        
        $bio = new BIO();
        $bio->msgBox('Cadastro efetuado com sucesso!');        
        $bio->redirectTo('/sample/sample.php');
    }

    /*public function alterarAluno(){
        //ao fazer uma alteração, os dados não modificados são desprezados
    }/**/
}

new Sample_Aluno();

erro retornado...

Fatal error: Can not call constructor in /var/www/sample/lib/Sample/Aluno.php on line 11

Como podem ver, quando instancio Sample_Aluno ela extende Sample_Pessoa e gostaria e o método __construct() deveria ser executado, retornando a saída OK, já que uma instancia de pessoa é criada automaticamente quando aluno é instanciada.

Editado por Rafael Laurindo
Link para o comentário
Compartilhar em outros sites

  • 0

Rafael,

Toma ai a coisa acontecendo..

<?php
//require_once 'Main.php';
/**
 * @author
 *
 */
class Sample_Pessoa{
    /**
     * @var unknown_type
     */
    public $nome;
    /**
     * @var unknown_type
     */
    protected $id = NULL;
    /**
     * @var unknown_type
     */
    protected  $_db;
    /**
     * @return unknown_type
     */
    public function __construct(){
        //$this->_db = new Sample_Main();
        echo 'OK!';
    }
    /**
     * @return unknown_type
     */
    private function obterPessoa(){
        $this->nome = $_POST['txtNome']; //acessando a propriedade "nome" da classe corrente pessoa
    }
    /**
     * @return unknown_type
     */
    protected function adicionarPessoa(){
        $this->obterPessoa();
        $add = "
            insert into pessoa(id, nome)
            values (NULL, ?)
        ";

        $stmt = $this->_db->_conn->prepare($add); //o prepare deve ser atrinuido a uma variável, para que a tal possa a acessar os métodos à fim
        $stmt->bindParam(1, $this->nome, PDO::PARAM_STR); //Vincula um parâmetro para uma variável especificada. Para cada " existe um índice que começa em 1

        if ($stmt->execute()){ //testa executando
            $id = "
                select max(id)
                from pessoa
            ";//se o código SQL estiver errado, alguma função pode não ser reconhecida como a fetchColumn()
            $this->id = $this->_db->_conn->query($id)->fetchColumn(); //Deve ser usado quando a busca for de apenas um valor. Retorna uma única coluna do conjunto de resultados da próxima linha
            //o fetchColumn() pode receber um valor numérico informando o número da coluna que deseja-se indexar
        }
    }
}

/**
 * @author
 *
 */
class Sample_Aluno extends Sample_Pessoa{
    /**
     * @return unknown_type
     */
    public function __construct(){
        parent::__construct();
    }
}

new Sample_Aluno();

abraços

Editado por ursolouco
Link para o comentário
Compartilhar em outros sites

  • 0

Rafael,

Sim, para o proposito levantado no tópico (invocar construtor da classe pai).

Acredito que sua dúvida esteja mais na parte conceitual do que na parte prática.

Veja um pouco de conceito no manual do php (http://www.php.net/manual/pt_BR/language.oop5.paamayim-nekudotayim.php)

Abraços

Funcionou na sua máquina? Não entendi o que você fez de diferente no meu código.

Link para o comentário
Compartilhar em outros sites

  • 0
Acredito que sua dúvida esteja mais na parte conceitual do que na parte prática.

Gosto muito de desenvolvimento, a parte técnica eu entendi. Só uma coisa eu n entendi muito bem, um atributo static deve ter um valor padrão certo? Esse valor pode ser NULL? De uma olhada nesse código:

<?php

class File{
    public static $handle = NULL;
    
    //o método __construct é executado automaticamente quando a classe é instanciada
    public function __construct(){        
        if($_POST['btnCarregar'] != NULL){
            $this->readToFile();
            $this->createHTML();
        }
        else
            if($_POST['btnSalvar'] != NULL)
                $this->writeToFile();
    }
    
    public function createPointer(){
        //abri o arquivo do servidor para leitura e cria o ponteiro
        self::$handle = fopen($_POST['txtFile'], "r+");
        if (!self::$handle){
            echo " 
                <script type=text/javascript>
                    alert('Arquivo ou diretório não encontrado')
                
                </script>
            ";     
        }
    }
    
    public function readToFile(){
        $this->createPointer();
        //le o conteúdo do arquivo e o armazena na propriedade txt da classe
        return fread(self::$handle, 10000);
    }
    
    public function writeToFile(){
        var_dump(self::$handle);
        //escreve no arquivo        
        //fwrite (self::$handle, $_POST['txtCode']);
        //fecha o ponteiro
        //fclose (self::$handle); 
    }
    
    public function createHTML(){
        $HTML="
            <!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>
            <html>
            <head>
            <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
            <title>Eclipse web - version 1.0</title>            
            </head>
            <body onload=''>
            <center>
            <form method='POST' action='File.php'>
                <textarea cols='117' rows='29' name='txtCode'/>".$this->readToFile()."</textarea><br/>
                <input type='submit' name='btnSalvar' value='Salvar'/>
                <input type='submit' name='btnCarregar' value='Carregar'/>
            </form>
            </center>
            </body>
            </html>
            ";
        //<textarea cols='117' rows='29' name='txtCode'/>".$this->readFile()."</textarea><br/>
        /*<script type='text/javascript'>
                function inner(id){
                    var elemId = document.getElementById(id)
                    elemId.innerHTML = ".$this->readFile()."
                }
            </script>/**/            
        echo $HTML; /**/
    }
}
//Ver comando que verifica se uma classe já está instanciada
//inicializa a classe
new File();

Essa classe que programei foi para manipular arquivos, uma parte funciona perfeitamente, mas o método writeToFile() não funciona bem. Minha idéia é a seguinte. Criar um ponteiro estático no método createPointer para que pudesse ser acessado ainda no método writeToFile, usei o fopen com o parâmetro r+ para que pudesse ser lido e escrito ao mesmo tempo, mas parece que quando instancio a classe o ponteiro é reinicializado, eu achava que a propriedade static conservava o valor atribuido ao atributo mesmo que a classe fosse instanciada novamente, mas parece que isso não acontece, nesse caso, gostaria de fazer para que uma classe já instanciada não fosse instanciada novamente para não reinicializar o atributo estático. Essa mesma classe é usada mais de uma vez, uma por um formulário HTML para ler o arquivo e coloca-lo em uma textarea e outra vez é usada por outro form para pegar o seu valor e grava-lo novamente no arquivo uma vez editado. Eu tenho uma solução, usar duas classes distintas, uma para criar o ponteiro e ler o arquivo e outra para ler, assim a mesma classe não seria instaciada mais de uma vez, mas creio que isso é gambiarra, gostaria de outras opiniões, pois nunca saberei tudo. Agradeço abraço.

Editado por Rafael Laurindo
Link para o comentário
Compartilhar em outros sites

  • 0
Só uma coisa eu n entendi muito bem, um atributo static deve ter um valor padrão certo?
Quem te falou isso ?

Eu posso ter um membro privado de uma classe como estatico sem ter inicializado :closedeyes:

if($_POST['btnCarregar'] != NULL){

$this->readToFile();

$this->createHTML();

}

Esta condição sempre vai acontecer, não acha ?

Rafael, vamos lá

//teste.php

<form method="POST" action="sb.php">
    <input type="hidden" name="txtFile" value="myfile.txt">
    <input type="submit" name="btnCarregar" value="Botão">
</form>
//sb.php
<?php

class File{

    public static $handle = null;

    //o método __construct é executado automaticamente quando a classe é instanciada
    public function __construct(){
    
        $this->createPointer();
    
        if($_POST['btnCarregar']){
            $this->readToFile();
            $this->createHTML();
        }

        if($_POST['btnSalvar'])
        {
            $this->writeToFile();
        }
    }

    public function createPointer(){
        //abri o arquivo do servidor para leitura e cria o ponteiro
        self::$handle = fopen($_POST['txtFile'], "r+");
        if (!self::$handle){
            echo "
                <script type=text/javascript>
                    alert('Arquivo ou diretório não encontrado');
                </script>
            ";
        }
    }

    public function readToFile(){
        $this->createPointer();
        //le o conteúdo do arquivo e o armazena na propriedade txt da classe
        return fread(self::$handle, 10000);
    }

    public function writeToFile(){
        //escreve no arquivo
        fwrite (self::$handle, $_POST['txtCode']);
        //fecha o ponteiro
        fclose (self::$handle);
        echo "sucesso!";
    }

    public function createHTML(){
        $HTML="
            <!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>
            <html>
            <head>
            <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
            <title>Eclipse web - version 1.0</title>
            </head>
            <body onload=''>
            <center>
            <form method='POST' action='sb.php'>
                <input type='hidden' name='txtFile' value='".$_POST['txtFile']."'>
                <textarea cols='117' rows='29' name='txtCode'>".$this->readToFile()."</textarea><br/>
                <input type='submit' name='btnSalvar' value='Salvar'>
                <input type='submit' name='btnCarregar' value='Carregar'>
            </form>
            </center>
            </body>
            </html>
            ";
        //<textarea cols='117' rows='29' name='txtCode'/>".$this->readFile()."</textarea><br/>
        /*<script type='text/javascript'>
                function inner(id){
                    var elemId = document.getElementById(id)
                    elemId.innerHTML = ".$this->readFile()."
                }
            </script>/**/
        echo $HTML; /**/
    }
}
//Ver comando que verifica se uma classe já está instanciada
//inicializa a classe
new File();
//myfile.txt
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!
OLA MUNDO!

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Obrigado por me ajudar, to gostando de suas explicações. Mas você atribui ao value do objeto tipo hidden o arquivo texto, eu esqueci de te explicar, o usuário escolherá o arquivo, digitando o endereço de onde se encontra em um objeto tipo text, daí ele clica em carregar e o texto do arquivo aparecerá no textarea, depois que ele fizer as alterações ele pode clicar em salvar e o conteúdo da textarea será salvo no arquivo texto no servidor. Entendeu? Com o ajax acho que seria ainda mais fácil, eu poderia fazer uma requisição ao arquivo php com o ajax.

Editado por Rafael Laurindo
Link para o comentário
Compartilhar em outros sites

  • 0

Rafael,

Entendi sim, mas isso é uma particularidade do sistema que você vai implementar, para o problema que você mencionou no tópico acho que sua dúvida já foi sanada.

Abraços

Obrigado por me ajudar, to gostando de suas explicações. Mas você atribui ao value do objeto tipo hidden o arquivo texto, eu esqueci de te explicar, o usuário escolherá o arquivo, digitando o endereço de onde se encontra em um objeto tipo text, daí ele clica em carregar e o texto do arquivo aparecerá no textarea, depois que ele fizer as alterações ele pode clicar em salvar e o conteúdo da textarea será salvo no arquivo texto no servidor. Entendeu? Com o ajax acho que seria ainda mais fácil, eu poderia fazer uma requisição ao arquivo php com o ajax.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,2k
    • Posts
      652k
×
×
  • Criar Novo...