Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

vieira.rrafael

[Resolvido] Erro ao carregar classe

Recommended Posts

Os códigos são os seguintes:

#Os namespaces seguem a estrutura do diretório onde está a classe.
<?php
namespace classes\utilities;

interface InterfaceController {

public function insert($object, $link_connection);
public function delete($object, $link_connection);
public function update($object, $link_connection);
public function select($id);
public function selectAll($link_connection);

}
?>

<?php
namespace classes\controllers;

use classes\models\Student;

#use classes\utilities\InterfaceController;

class StudentController/* implements InterfaceController */{

   private $contactController;
   private $filiationController;

   public function __construct() {
       $this->contactController = new ContactController();
       $this->filiationController = new FiliationController();
   }

   public function delete($object, $link_connection) {

   }

   public function selectAll($link_connection) {

   }

   public function insert(Student $object, \PDO $link_connection) {
       try {

           $prepare = $link_connection->prepare("insert into student(name, registration)
           values(:name, :registration)");
           $prepare->execute(array(
               ":name" => $object->getName(),
               ":registration" => $object->getRegistration()
           ));
           $object->setId($link_connection->lastInsertId());
           $this->contactController->insert($object, $link_connection);
           $this->filiationController->insert($object, $link_connection);
       } catch (Exception $e) {
           return $e;
       }
   }

   public function select($id) {

   }

   public function update($object, $link_connection) {

   }

}
?>

#esse é o index.php onde tudo isso é executado
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
   <head>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
       <title></title>
   </head>
   <body>
       começou <br/> <br/>
       <?php
       spl_autoload_register(function ($class) {
                   require_once str_replace("\\", "/", $class . '.php');
                 # essas três últimas linhas são para mostrar quando as classes param de ser carregadas
                   echo "arquivo -> " . str_replace("\\", "/", $class . '.php') . "<br/>";
                   echo "namespace -> " . $class . "<br/>";
                   echo "<br/>";
               });

use classes\utilities\ConnectionManager;
use classes\models\Contact;
use classes\models\Filiation;
use classes\models\Student;
use classes\controllers\StudentController;

$pdo = ConnectionManager::getConnection();
       $student = new Student();
       $contact = new Contact();
       $filiation = new Filiation();
       $studentController = new StudentController();
       try {
           $pdo->beginTransaction();

           $filiation->setFather("Father Exemplo")->setMother("Mother Exemplo");
           $contact->setCell_phone("1234-5678")->setEmail("exemplo@email.com");

           $student->setContact($contact)->setFiliation($filiation)
                   ->setName("Exemplo")->setRegistration("2011A45");

           $studentController->insert($student, &$pdo);
           $pdo->commit();
           echo "sucesso" . "<br/>";
       } catch (Exception $e) {
           echo $e->getMessage() . "<br/>";
           echo "arquivo " . $e->getFile() . "<br/>";
           echo "linha " . $e->getLine() . "<br/>";
           $pdo->rollBack();
           echo "falhou!" . "<br/>";
       }

       ConnectionManager::closeConnection($pdo);
       ?>
       terminou
   </body>
</html>

 

Com essas linhas comentadas, tudo funciona.

#use classes\utilities\InterfaceController;

class StudentController /*implements InterfaceController */{

 

O resultado impresso por autload é esse:

começou 

arquivo -> classes/utilities/ConnectionManager.php
namespace -> classes\utilities\ConnectionManager

arquivo -> classes/models/Student.php
namespace -> classes\models\Student

arquivo -> classes/models/Contact.php
namespace -> classes\models\Contact

arquivo -> classes/models/Filiation.php
namespace -> classes\models\Filiation

arquivo -> classes/controllers/StudentController.php
namespace -> classes\controllers\StudentController

arquivo -> classes/controllers/ContactController.php
namespace -> classes\controllers\ContactController

arquivo -> classes/controllers/FiliationController.php
namespace -> classes\controllers\FiliationController

sucesso
terminou

Com o trecho supracitado descomentado, o resultado é esse:

começou 

arquivo -> classes/utilities/ConnectionManager.php
namespace -> classes\utilities\ConnectionManager

arquivo -> classes/models/Student.php
namespace -> classes\models\Student

arquivo -> classes/models/Contact.php
namespace -> classes\models\Contact

arquivo -> classes/models/Filiation.php
namespace -> classes\models\Filiation

arquivo -> classes/utilities/InterfaceController.php
namespace -> classes\utilities\InterfaceController

Ou seja, depois de carregar a classe InterfaceController.php, o programa encerra. Assim, sem mais nem menos!

Qual o mistério? Por que a interface bagunça tudo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Em primeiro lugar: por que um namespace classes? Meio redundante...

Em segundo lugar: use uma convenção mais apropriada para interfaces, como IController ao invés de InterfaceController.

Em terceiro lugar, métodos de interface são SEMPRE públicos. Não especifique o encapsulamento.

 

Por fim, a classe que implementa uma interface deve implementar os métodos com assinatura IDÊNTICAS:

 

public function insert($object, $link_connection);

public function insert(Student $object, \PDO $link_connection) {...

 

Viu a diferença?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Em primeiro lugar: por que um namespace classes? Meio redundante...

Não tem nada de redundante Jaime.

 

Como ele não modifica o include_path, o autoload buscaria as classes a partir do diretório classes.

 

O mesmo poderia ser feito se ele alterasse o include_path aidicionando um diretório Libraries, por exemplo.

Assim buscaria dentro de Libraries sem a necessidade desse termo aparecer no namespace, podendo até mesmo remover o classes poruma estrutura diferenciada.

 

Em segundo lugar: use uma convenção mais apropriada para interfaces, como IController ao invés de InterfaceController.

Convenção de nomenclatura é você quem cria. Não existe um padrão internacional entre programadores do mundo que define que uma interface TEM de ser IController.

 

Se ele prefer ControllerInterface ou, de repente, InterfaceController e se sente confortável com isso, tudo bem.

 

O que elenão pode é, de repente mudar a nomenclatura adotada em algumas interfaces e esquecer-se de padronizar nas outras, senão vai se perder com o tempo.

 

Em terceiro lugar, métodos de interface são SEMPRE públicos. Não especifique o encapsulamento.

Tudo bem, mas e qual a diferença? Eu mesmo mantenho a visibilidade nas interfaces, mais por uma questão de organização, afinal, algumas de minhas interfaces são geradas dinâmicamente, isto é, uma ferramenta que reflete uma classe, lista os métodos públicos que devem existir e gera o PHP pra mim.

 

Um bom exemplo é minha View. Ao invés de criar uma AbstractView por exemplo, tenho apenas a classe concreta que implementa IView. Ao longo do sistema eu só aceito como argumento uma IView.

 

Qualquer que seja a classe responsável (um adaptador Smarty, por exemplo), se não implementar IView, tornar-se-á inútil. E se implementar, terá aqueles métodos.

 

Por fim, a classe que implementa uma interface deve implementar os métodos com assinatura IDÊNTICAS:

 

public function insert($object, $link_connection);

public function insert(Student $object, \PDO $link_connection) {...

 

Viu a diferença?

Exato. Aliás, menino_levado, você não viu nenhum erro por usar uma implementação como essa?

 

Agora, isso:

 

use classes\utilities\InterfaceController;

Comentado ou não comentado não vai mudar nada, afinal está apenas importando a interface a partir do namespace passado.

 

A partir do momento que você usa o implements é que vai passar a dar problema, e acredito que esse break esteja ocorrendo justamente pelo fato de você não estarrespeitando a interface.

 

Certeza mesmo só se tivéssemos acesso aos erros mostrados.

 

A propósito, você está usando, no começo do sistema (index.php) isso:

 

ini_set( 'display_errors', TRUE );

error_reporting( E_ALL | E_STRICT );

É sempre uma boa prática fazê-lo durante o desenvolvimento.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bruno, namespace classes é redundante SIM. É meio evidente que sejam classes em um namespace e não é pelo fato de que as classes ficam numa pasta classes raiz que isso faça sentido, uma vez que a função autoload tem uma implementação propria.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então, pode ser redundância de nomenclatura, mas nada impede que seja usado, entende?

 

Vai do gosto da pessoa, assim como o dito a respeito da forma como se defne o nomede uma interface.

Compartilhar este post


Link para o post
Compartilhar em outros sites

É claro que pode, mas pelo jeito não era uma questão de GOSTO da pessoa, e sim pelo fato de organizar os arquivos fonte numa pasta chamada classes.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Em primeiro lugar: por que um namespace classes? Meio redundante...

#eu organizei assim:
meu_projeto/
   classes/
       utilities/
       controllers/
       models/
       views/
   js/
   imagens/
   # assim por diante
   index.php

#E achei organizado.

Em segundo lugar: use uma convenção mais apropriada para interfaces, como IController ao invés de InterfaceController.

 

'Conheço' uma nomeclatura, criada por um engenheiro da Microsoft(se não me falha a memória) parecida, se não for a mesma, que tem um prefixo para cada

tipo de dado: i para inteiro, b para boolean e segue assim.

$iidade;
$bempty;
#Não gosto dela.

 

Por fim, a classe que implementa uma interface deve implementar os métodos com assinatura IDÊNTICAS:

 

public function insert($object, $link_connection);

public function insert(Student $object, \PDO $link_connection) {...

 

Viu a diferença?

Exato. Aliás, menino_levado, você não viu nenhum erro por usar uma implementação como essa?

Agora, isso:

 

use classes\utilities\InterfaceController;

Comentado ou não comentado não vai mudar nada, afinal está apenas importando a interface a partir do namespace passado.

 

A partir do momento que você usa o implements é que vai passar a dar problema, e acredito que esse break esteja ocorrendo justamente pelo fato de você não estarrespeitando a interface.

 

Certeza mesmo só se tivéssemos acesso aos erros mostrados.

 

A propósito, você está usando, no começo do sistema (index.php) isso:

 

ini_set( 'display_errors', TRUE );

error_reporting( E_ALL | E_STRICT );

É sempre uma boa prática fazê-lo durante o desenvolvimento.

 

Pensei que na implementação da interface poderia forçar um 'tipo de dado' e que isso não interferiria no código porque o php não tem tipagem forte como o java. tolo engano meu!!!

Não estava usando

ini_set( 'display_errors', TRUE );
error_reporting( E_ALL | E_STRICT );

. Erro que não vou mais cometer(espero).

O erro estava aqui:

public function insert(/*-> */Student $object,/* -> */ \PDO $link_connection) {
       try {

           $prepare = $link_connection->prepare("insert into student(name, registration)
           values(:name, :registration)");

 

ficou assim:

public function insert($object, $link_connection) {
       try {

           $prepare = $link_connection->prepare("insert into student(name, registration)
           values(:name, :registration)");

E agora funciona!

Problema resolvido!

Grato a todos!

 

É claro que pode, mas pelo jeito não era uma questão de GOSTO da pessoa, e sim pelo fato de organizar os arquivos fonte numa pasta chamada classes.

Exatamente!!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu já suspeitava dessa sua hierarquia. O que o Jaime deve ter achado é que você poderia ter dado outro nome ao invés de classes (Libraries, por exemplo).

 

Mas assim, o PHP não tem tipagem forte como Java, porém com o recurso de type hinting você pode forçar um parâmetro a ser de um determinado tipo, no caso, instância de uma classe ou objeto que implemente uma interface.

 

Daí sim. Se você definir que o parâmetro deve ser Student, qualquer valor que você passar diferente disso vai ser negado.

 

Quanto a nomeclatura, se não me engano é chamado de estilo húngaro e se aplica às variáveis (em conjunto com camelCase): $sString, $bBoolean, $iInteger...

 

Para Interfaces e classes abstratas dependende do programador, já que infelizmente Abstract e Interface são palavras reservadas até mesmo quando usadas em um namespace.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.