quinta-feira, 26 de julho de 2012

Late Static Binding no PHP

Late Static Binding existe a partir do PHP 5.3 e a maioria das explicações não são muito claras e por isso essa funcionalidade fica meio na... nuvem! 


A documentação do PHP define o Late Static Binding como "maneira de referenciar a classe chamada no contexto de herança estática"
ENTENDEU? 


Esta definição apesar de palavras bem usadas no nosso dia a dia não deixou muito claro a sua finalidade e ai ficamos muuito confusos... Felizmente esse é o tipo de conceito que não se entra na cabeça de "prima" e para ajudar a documentação do PHP tem bastante exemplo.

Chega de papo, a melhor forma de entender isso é vendo o CÓDIGO!

Para usar a Late Static Binding, precisamos de uma classe que herda de outra classe e alguns métodos estáticos para sobreescrevemos. Veja:

Late static binding - php 5.3
  1. class classePai {
  2.    
  3.     public static function normalCall() {
  4.         self::calledMethod();
  5.     }  
  6.     public static function lateStaticCall() {
  7.         static::calledMethod();
  8.     }  
  9.     public static function calledMethod() {
  10.         echo " Chamada na classe PAI \n";
  11.     }  
  12.    
  13. }
  14. class classeFilha extends classePai {
  15.    
  16.     public static function calledMethod() {
  17.         echo "Chamada na classe Filha \n";
  18.     }  
  19.    
  20. }


Veja bem, temos a classeFilha que extende da classePai...
Na classePai temos 3 métodos estáticos, normalCalllateStaticCallcalledMethod na classe filha temos apenas um método estático o calledMethod

Percebam que tanto na filha quanto na pai temos a classe calledMethod certo?
Pois bem, se chamarmos o método estático normalCall tanto com a classe filha como a pai o resultado seria  Chamada na classe PAI  veja um pequeno exemplo do uso.


USANDO FORMA COMUM PARA CHAMAR OUTRO METODO ESTATICAMENTE
  1.  classePai::normalCall(); // Chamada na classe PAI
  2.  classeFilha::normalCall(); // Chamada na classe PAI


Ou seja, independente de chamar o método estático na filha ou na pai a função que a classe normalCall irá chamar sempre será a calledMethod da classe pai, pois é isso que o self esta fazendo.

Agora, se fizermos a mesma coisa mais trocando o self por static que é como esta implementado no método lateStaticCall a chamada seria diferente pois o Late Static Binding estaria em ação, veja:

USANDO LATE STATIC BINDING NO PHP
  1.  classePai::lateStaticCall(); // Chamada na classe PAI
  2.  classeFilha::lateStaticCall(); // Chamada na classe Filha


Fonte: PHP.net (como sempre, rs)

quarta-feira, 25 de julho de 2012

Tirinha engraçada para devs

Oi amigos. Hoje não vou falar nada demais. Apenas armazenar aqui em meu blog uma tirinha que eu acho espetacular, veja:




Tradução(não levem no pé da letra):
Uma mulher atende o telefone em sua casa e...


Telefone
Olá Senhora, aqui é da escola de seu filho.
A ligação é pq tivemos alguns problemas com o nosso sistema.

Mãe

Oh, o que aconteceu? Ele quebrou alguma coisa?


Telefone
De uma certa maneira sim.... O nome do seu filho é mesmo  Robert'); DROP TABLE Students; -- ?

Mãe
Oh, é sim... chamamos ele de Little Bobby Tables



Telefone
Pois bem, por culpa disso perdemos o registro de todos nossos alunos. Espero que vc esteja feliz.


Mãe
E espero que você tenha aprendido a validar a entrada de dados no banco...


OU SEJA? CHUPA! Oaksoaksokasokasok.... EURI...



quarta-feira, 18 de julho de 2012

Auto relacionamento no DOCTRINE

Olá amigos tudo bem? Esse artigo é para vc que precisa fazer um auto relacionamento(Self-reference) utilizando o DOCTRINE.


Existem 3 formas de relacionamentos e vamos aborda-las aqui que são:
1. Um para Um (One-To-One)
2. Um para Muitos (One-To-Many)
3. Muitos para Muitos (Many-To-Many)



Podemos facilmente ter uma referência de qualquer um desses caras, vamos aos exemplos


1. Um para Um (One-To-One Doctrine)
Estudante para mentor, só pode ter um e ele também é estudante. (arrumando o exemplo antigo)



  
  1. <?php
  2. /** @Entity */
  3. class Estudante
  4. {
  5.     // ...
  6.  
  7.     /**
  8.      * @OneToOne(targetEntity="Estudante")
  9.      * @JoinColumn(name="mentor_id", referencedColumnName="id")
  10.      */
  11.     private $mentor;
  12.  
  13.     // ...
  14. }



O uso do @JoinColumn é opcional já que seria definido por padrão então pois cnh_id e o id são os mesmos, podemos omiti-lo por padrão.


2. Um para Muitos (One-To-Many)

Imagine um caso de um forum, onde uma opinião pode receber 'n' opiniões (opinião da opinião)



  1. class ForumOpiniao {
  2.     /**
  3.      * @OneToMany(targetEntity="ForumOpiniao", mappedBy="forum_opiniao", cascade={"persist", "remove"})
  4.      */
  5.     private $filhos;
  6.     /**
  7.      * @ManyToOne(targetEntity="ForumOpiniao", inversedBy="filhos")
  8.      * @JoinColumn(name="forum_opiniao", referencedColumnName="id")
  9.      */
  10.     private $forum_opiniao;
  11. //.....
  12. }

Veja que criamos o atributo forum_opiniao que referencia a ele mesmo e os filhos para armazenar os filhos desse pai.


3. Muitos para Muitos (Many-To-Many)

Um caso onde usuarios poderiam se referenciar



  1. <?php
  2. /** @Entity */
  3. class User
  4. {
  5.     // ...
  6.     /**
  7.      * @ManyToMany(targetEntity="User", mappedBy="myFriends")
  8.      */
  9.     private $friendsWithMe;
  10.     /**
  11.      * @ManyToMany(targetEntity="User", inversedBy="friendsWithMe")
  12.      * @JoinTable(name="friends",
  13.      *      joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
  14.      *      inverseJoinColumns={@JoinColumn(name="friend_user_id", referencedColumnName="id")}
  15.      *      )
  16.      */
  17.     private $myFriends;
  18.     public function __construct() {
  19.         $this->friendsWithMe = new \Doctrine\Common\Collections\ArrayCollection();
  20.         $this->myFriends = new \Doctrine\Common\Collections\ArrayCollection();
  21.     }
  22.     // ...
  23. }

Básico e prático não achou?



Fonte: http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/reference/association-mapping.html

segunda-feira, 16 de julho de 2012

Criando INDICE no DOCTRINE

Vc que precisa criar INDICES no Doctrine o processo é simples e fazemos isso nas annotations veja:

Usado dentro da annotation @Table sobre o nível de entidade de classe. Ele permite que a dica do SchemaTool para gerar um índice de banco de dados sobre as colunas da tabela especificada. Ela só tem sentido no contexto de geração de esquema SchemaTool.
Required attributes:
  • name: Name of the Index
  • columns: Array of columns.
Exemplo:
<?php
/**
 * @Entity
 * @Table(name="ecommerce_products",indexes={@index(name="search_idx", columns={"name", "email"})})
 */
class ECommerceProduct
{
}



MongoDB ODM


  1. <?php
  2. namespace Documents;
  3. /** @Document */
  4. class User
  5. {
  6.     /** @Id */
  7.     public $id;
  8.     /** @String @Index(unique=true, order="asc") */
  9.     public $username;
  10. }

Criamos um indice no campo "username", veja um exemplo simples para criar multiplos indices.




  1. <?php
  2. /**
  3.  * @Document
  4.  * @Indexes({
  5.  *   @Index(keys={"accountId"="asc"}),
  6.  *   @Index(keys={"username"="asc"})
  7.  * })
  8.  */
  9. class User
  10. {
  11.     /** @Id */
  12.     public $id;
  13.     /** @Integer */
  14.     public $accountId;
  15.     /** @String */
  16.     public $username;
  17. }


Você pode especificar índices em entidades incorporadas como você faz em entidades normais. Quando o Doctrine cria os índices para uma entidade podera também criar os índices de suas entidades mapeadas; 



  1. <?php
  2. namespace Documents;
  3. /** @Document */
  4. class BlogPost
  5. {
  6.     // ...
  7.     /** @Field(type="string") @Index */
  8.     private $slug;
  9.     /** @EmbedMany(targetDocument="Comment") */
  10.     private $comments;
  11. }

Mais informações: http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/indexes.html#unique-index