Avatar billede spyrodrag Nybegynder
21. marts 2006 - 13:48 Der er 12 kommentarer og
1 løsning

Typecasting til interface

Hej.
Jeg roder normalt med CSharp, men har nu fået til opgave at løse nogle opgaver i PHP. Dog er jeg lidt i tvivl om typecasting i PHP.

Koden:
----------------------------------
<?php
  interface IBind
  {
    static function IsFreeDomain($domain);
    static function IsValidDomain($domain);
  }
 
  interface IDisposable
  {
    function Dispose();
  }
 
  class Bind implements IBind, IDisposable
  {
    public static function IsFreeDomain($domain)
    {
      /*
      Bind::IsFreeDomain("static call");
     
      $bind = new Bind;
      $bind->IsFreeDomain("dynamic call");
      $bind->Dispose(); // remember this call!
      */
    }
   
    public static function IsValidDomain($domain)
    {
    }
   
    public function Dispose()
    {
    }
  }
 
  $bind = new Bind();
  $iBind = (IBind) $bind; // DETTE FEJLER
  $iBind->IsFreeDomain("www.test.dk");
  $bind->Dispose();
?>
----------------------------------

Findes der en måde, hvorpå man kan typecaste til et af de interfaces, som en klasse har forpligtet sig til at implementere?

Venlig hilsen,
Martin.
Avatar billede fangel Nybegynder
21. marts 2006 - 14:31 #1
Der tror jeg desværre at du har kastet dig ud i for advanceret OOP til at PHP kan være med..

Rimeligt generelt kan man ikke typecast til bestemte typer objekter.. Du kan tjekke
http://dk.php.net/language.types.type-juggling hvorfra dette citat også er:

The casts allowed are:
  * (int), (integer) - cast to integer
  * (bool), (boolean) - cast to boolean
  * (float), (double), (real) - cast to float
  * (string) - cast to string
  * (array) - cast to array
  * (object) - cast to object

Morten
Avatar billede spyrodrag Nybegynder
21. marts 2006 - 14:39 #2
Hej Morten.

Mange tak for dit svar. Jeg havde faktisk forsøgt at teste nogle af de eksempler du forslår der, og de virker fint. Det er virkelig ærgerligt at man ikke skal angive hvilken type variabel man har med at gøre i PHP. Det er desværre en stor mangel IMO.
Jeg lader lige tråden stå åben lidt endnu, for at se om der er nogen der har nogle andre gode idéer, ellers har du scoret dig 200 points.

Venlig hilsen,
Martin.
Avatar billede fangel Nybegynder
21. marts 2006 - 14:45 #3
Martin: Ja, personligt så jeg også gerne at PHP havde en større mulighed for at angive typer..

Men man kan - i PHP5, men det kører du kan jeg se - lave en smule type hinting i funktions kald.. Man kan nemlig angive hvilken klasse et bestemt argument skal være..

fx
function addFoo(Foo $foo) {

}
vil fejle hvis ikke $foo er af typen Foo eller en underklasse - altså som man kender det fra mere statiske sprog..

Morten
Avatar billede spyrodrag Nybegynder
21. marts 2006 - 15:13 #4
Hej Morten.

Det ser ud til at du har ret i at det ikke kan lade sig gøre. Jeg har læst lidt på PHP.net, og har fundet ud af at man kan typecaste fra klasse til klasse, men ikke fra klasse til interface :-(.

Kode:
----------------------------------
  function typecast($old_object, $new_classname)
  {
    if(class_exists($new_classname) || interface_exists($new_classname))
    {
      $old_serialized_object = serialize($old_object);
      print_r($old_serialized_object, true);;
      $new_serialized_object = 'O:' . strlen($new_classname) . ':"' . $new_classname . '":' .
                              substr($old_serialized_object, $old_serialized_object[2] + 7);
                             
      echo $new_serialized_object;
      return unserialize($new_serialized_object);
    }
    else
      return false;
  }

  $bind = new Bind();
  $iBind = typecast($bind, "IBind");
  $iBind->IsFreeDomain("www.test.dk");
  $bind->Dispose();
----------------------------------

Fejler, når man kommer med et interface.

Venlig hilsen,
Martin.
Avatar billede fangel Nybegynder
21. marts 2006 - 15:22 #5
Du kan (måske) prøve at lave abstrakte klasser istedet for interfaces.. - selvom jeg tror at PHP vil pive ganske meget hvis man prøver at lave en instance af en abstrakt klasse..

PS, i tilfælde af at du skulle være i tvivl, så er den metode du har fundet et af de større hacks jeg har set gennem tiden..

Morten
Avatar billede spyrodrag Nybegynder
21. marts 2006 - 15:33 #6
Hehe...
Jeg dropper det her typecasting. Det ville bare være smart. Smid bare et svar, så får du alle points. - tak for din tid.

Venlig hilsen,
Martin.
Avatar billede fangel Nybegynder
21. marts 2006 - 15:41 #7
Pjat pjat - hva skal man bruge point til - desuden svarede jeg jo ikke på dit spørgsmål ;)

Behold du bare dem.. er godt nok faldet ned under top 200, men jeg har så heller ikke været aktiv i et års tid.. og skrev kun fordi jeg faldt over et "interesant" spørgsmål.. ;)

Morten
Avatar billede spyrodrag Nybegynder
22. marts 2006 - 09:09 #8
Hej Morten.

Det er dejligt at se at folk er så hjælpsomme herinde. Ved du om man på nogen måde har mulighed for at checke om en klasse har et interface i sig?

Venlig hilsen,
Martin.
Avatar billede fangel Nybegynder
22. marts 2006 - 09:14 #9
Du kan tjekke om et klasse er, eller nedarver fra en anden klasse eller et interface ved at lave

if( $obj instanceof Class_or_Interface ) {
..
}

instanceof er en php5 operator, og i php4 var der vidst nok en is_a($obj, 'Class');

*host* ##php på irc.freenode.net - lidt bedre hvis man har "advancerede" php-sprøgsmål.. og jeg hænger ud der.. ;)

Morten
Avatar billede spyrodrag Nybegynder
22. marts 2006 - 19:28 #10
Hej Morten.

Hvilket "nick" gemmer du dig bag?

Venlig hilsen,
Martin.
Avatar billede fangel Nybegynder
23. marts 2006 - 08:34 #11
Samme som igen, "fangel" ;)
Avatar billede spyrodrag Nybegynder
10. oktober 2006 - 08:10 #12
Lukning af tråd.
Avatar billede fangel Nybegynder
10. oktober 2006 - 10:45 #13
shush martin, shush.. ;)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester