Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> trait vs interface
kayman
post
Post #1





Grupa: Zarejestrowani
Postów: 556
Pomógł: 40
Dołączył: 20.07.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


może chcę za dużo pisząc takie?


  1.  
  2. trait Tr {
  3.  
  4. public function getC() {
  5. echo 'asd';
  6. }
  7.  
  8. }
  9. }
  10.  
  11.  
  12. interface In {
  13.  
  14. public function getC();
  15.  
  16. }
  17.  
  18.  
  19. class B extends A implements In {
  20.  
  21. public function getC() {
  22. echo 'asd';
  23. }
  24.  
  25. }
  26.  
  27.  
  28. // a to wywala błąd
  29.  
  30.  
  31. class B extends A implements In {
  32.  
  33. use Tr;
  34.  
  35.  
  36. }
  37.  
  38.  


czyżby interface nie rozpoznaje metod wstrzykniętych przez trait?

Ten post edytował kayman 26.01.2015, 12:33:41
Go to the top of the page
+Quote Post
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Cytat
a to wywala błąd
Nie uważasz, że informacja jaki błąd mogłaby być pomocna? I co to jest klasa A?

Ten post edytował Crozin 26.01.2015, 12:35:19
Go to the top of the page
+Quote Post
kayman
post
Post #3





Grupa: Zarejestrowani
Postów: 556
Pomógł: 40
Dołączył: 20.07.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


jak jest

  1.  
  2. class B extends A implements In {
  3.  
  4. use Tr;
  5.  
  6. }
  7.  


wywala błąd o braku metody

a jak zdejmę interface

  1.  
  2. class B extends A {
  3.  
  4. use Tr;
  5.  
  6. }
  7.  


kod działa
Go to the top of the page
+Quote Post
Pyton_000
post
Post #4





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


  1. <?php
  2.  
  3. trait Tr {
  4. public function getC()
  5. {
  6. echo 'getC Trait'.PHP_EOL;
  7. }
  8. }
  9.  
  10. interface In {
  11. public function getC();
  12. }
  13.  
  14. class A {
  15.  
  16. }
  17.  
  18. class B extends A implements In
  19. {
  20. public function getC()
  21. {
  22. echo 'getC Class B'.PHP_EOL;
  23. }
  24.  
  25. }
  26.  
  27. class C extends A implements In
  28. {
  29. use Tr;
  30. }
  31.  
  32. $b = new B();
  33. $c = new C();
  34.  
  35. $b->getC();
  36. $c->getC();


Ten post edytował Pyton_000 26.01.2015, 12:46:16
Go to the top of the page
+Quote Post
Crozin
post
Post #5





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


  1. <?php
  2.  
  3. interface In {
  4. function getC();
  5. }
  6.  
  7. trait Tr {
  8. public function getC() {
  9. return 'Tr.getC()';
  10. }
  11. }
  12.  
  13. class A {
  14.  
  15. }
  16.  
  17. class B1 extends A implements In {
  18. public function getC() {
  19. return 'B1.getC()';
  20. }
  21. }
  22.  
  23. class B2 extends A implements In {
  24. use Tr;
  25. }
  26.  
  27. class B3 extends A {
  28. use Tr;
  29. }
  30.  
  31. $b1 = new B1();
  32. $b2 = new B2();
  33. $b3 = new B3();
  34.  
  35. var_dump($b1->getC());
  36. var_dump($b2->getC());
  37. var_dump($b3->getC());
  38. var_dump($b1 instanceof In);
  39. var_dump($b2 instanceof In);
  40. var_dump($b3 instanceof In);
Kod
string(9) "B1.getC()"
string(9) "Tr.getC()"
string(9) "Tr.getC()"
bool(true)
bool(true)
bool(false)
Jak widać wszystko w porządku.

EDIT: Pyton_000 mnie trochę wyprzedził.

Ten post edytował Crozin 26.01.2015, 12:47:17
Go to the top of the page
+Quote Post
kayman
post
Post #6





Grupa: Zarejestrowani
Postów: 556
Pomógł: 40
Dołączył: 20.07.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


a teraz już zgłupiałem, co ma metoda z parenta wspólnego z interface?

Kod
Fatal error: Declaration of Framework\Models\Master\MasterModel::setData() must be compatible with Framework\Models\Master\ModelInerface::setData($id) in C:\xampp\htdocs\lpcms\Framework\Models\Master\TableUsers.php on line 18



  1.  
  2. interface ModelInerface {
  3.  
  4. public function __construct();
  5.  
  6. public function setData($id);
  7.  
  8. public function __set($key, $value);
  9.  
  10. public function __get($key);
  11.  
  12. public function getAll($order = null);
  13.  
  14. public function save();
  15.  
  16. public function getData($id = null);
  17.  
  18. public function delete($id);
  19.  
  20. }
  21.  
  22. trait ModelTraits {
  23.  
  24.  
  25. public function setData($id) {
  26. parent::setData($this->table, $this->columns, $id);
  27. }
  28.  
  29. public function __set($key, $value) {
  30. $this->set($this->table, $key, $value);
  31. }
  32.  
  33. public function __get($key) {
  34. return $this->get($this->table, $key);
  35. }
  36.  
  37. public function getAll($order = null) {
  38. return parent::getAll($this->table, $this->columns, $order);
  39. }
  40.  
  41. public function save() {
  42. parent::save($this->table);
  43. }
  44.  
  45. public function getData($id = null) {
  46. if ($id)
  47. $this->setData($id);
  48. return parent::getData($this->table);
  49. }
  50.  
  51. public function delete($id) {
  52. parent::delete($this->table, $id);
  53. }
  54.  
  55. }
  56.  
  57.  
  58. class TableUsers extends MasterModel implements ModelInerface {
  59.  
  60. private $table = 'users';
  61. private $columns = array('id', 'mail', 'pass', 'level', 'firstname', 'lastname', 'lang');
  62.  
  63. public function __construct() {
  64. parent::__construct($this->table, $this->columns);
  65. }
  66.  
  67. use ModelTraits;
  68.  
  69. // cut
  70.  
  71. }
  72.  
  73. class MasterModel {
  74.  
  75. public $data;
  76.  
  77. public function __construct($table, $columns) {
  78. foreach ($columns as $value) {
  79. $this->data[$table][$value] = null;
  80. }
  81. }
  82.  
  83. public function setData($table, $columns, $id) {
  84. $query = new QueryBuider();
  85. $query->setColumns($columns);
  86. $query->setFrom($table);
  87. $query->addWhere('id', $id);
  88. $sql = \Framework\Libs\Sql::instance();
  89. $data = $sql->getSingleRow($query->getSelect());
  90. foreach ($columns as $value) {
  91. $this->data[$table][$value] = $data[$value];
  92. }
  93. }
  94.  
  95. // cut
  96.  
  97. }
  98.  
  99.  

Go to the top of the page
+Quote Post
Pyton_000
post
Post #7





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


To że deklarujesz kontrakt (interfejs) z jednym parametrem a deklarujesz metodę z 3. To jest niezgodność deklaracji z interfejsem.
Go to the top of the page
+Quote Post
Crozin
post
Post #8





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Masz niekompatybilne sygnatury metod. Nie ma to żadnego związku z interfejsami czy traitsami.
  1. class A
  2. {
  3. public function abc($abc, $cde, MyClass $def)
  4. {
  5. // jakaś implementacja
  6. }
  7. }
  8.  
  9. class B extends A
  10. {
  11. public function abc($abc, $cde, def) // błąd, niekompatybilne sygnatury
  12. {
  13. // jakaś implementacja
  14. }
  15.  
  16. public function abc() // błąd, niekompatybilne sygnatury
  17. {
  18. // jakaś implementacja
  19. }
  20.  
  21. public function abc($abc, $cde, MyClass $def) // OK
  22. {
  23. // jakaś implementacja
  24. }
  25. }

Go to the top of the page
+Quote Post
kayman
post
Post #9





Grupa: Zarejestrowani
Postów: 556
Pomógł: 40
Dołączył: 20.07.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


czyli to jest żle i trzeba by np. inaczej nazwać metodę w parencie

  1.  
  2. public function setData($id) {
  3. parent::setData($this->table, $this->columns, $id);
  4. }
  5.  
  6. //zmienić np tak
  7.  
  8. public function setData($id) {
  9. $this->setMasterData($this->table, $this->columns, $id);
  10. }
  11.  
  12.  


a to dobrze

  1.  
  2. public function __get($key) {
  3. return $this->get($this->table, $key);
  4. }
  5.  


Ten post edytował kayman 26.01.2015, 14:19:58
Go to the top of the page
+Quote Post
Crozin
post
Post #10





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


1. Wykorzystanie magicznego __get() jest raczej złym pomysłem. Dlaczego nie zrobisz zwykłej metody get(), getTableProperty() czy jakkolwiek inaczej nazwanej?
2. Nie wiem co dokładnie chcesz osiągnąć, więc ciężko napisać co byłoby dobrym rozwiązaniem.
Go to the top of the page
+Quote Post
kayman
post
Post #11





Grupa: Zarejestrowani
Postów: 556
Pomógł: 40
Dołączył: 20.07.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


chciałem np takie coś

  1.  
  2. $id = getNpZSessji();
  3.  
  4. $user = new TableUser();
  5.  
  6. $user->setData($id);
  7.  
  8. echo 'Witaj ' . $user->firstname . '. Twoje id to '. $user->id;
  9.  
  10.  
  11. //lub
  12.  
  13. $user = new TableUser();
  14.  
  15. $user->setData($id);
  16.  
  17. $user->firstame = 'Tomek';
  18.  
  19. $user->save(); // jest id -> update;
  20.  
  21. //albo
  22.  
  23. $user = new TableUser();
  24.  
  25. $user->firstame = 'Tomek';
  26. //$user->lastname = costam etc
  27.  
  28. $user->save(); // brak id -> insert;
  29.  


i analogicznie do wszystkich tabel w bazie danych takie mapowanie

do tego np takie konstrukcje incydentalne do poszczególnych tabel

  1.  
  2. $log = new TableLogs();
  3. $log->addLog('zmiana wartości tu i tu');
  4.  
  5. // co jest równoznaczne z
  6.  
  7. $log = new TableLogs();
  8. $log->addtime = mktime();
  9. $log->user_id = $SESSION['user_id'];
  10. $log->content = 'zmiana wartości tu i tu';
  11. $log->save();
  12.  
  13.  


Go to the top of the page
+Quote Post
Pyton_000
post
Post #12





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


setData możesz spokojnie wywalić i dać w konstruktor.

W tym przypadku nie potrzebujesz ogólnie interfejsu.

Robisz sobie klasę bazową Model która zastępuje Ci trait i interface (możesz zrobić abstract żeby jej nie instancjować) a poszczególne modele extends Model i wsio. Nie ma co kombinować (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
kayman
post
Post #13





Grupa: Zarejestrowani
Postów: 556
Pomógł: 40
Dołączył: 20.07.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat(Pyton_000 @ 26.01.2015, 15:48:51 ) *
setData możesz spokojnie wywalić i dać w konstruktor.


imo nie -> bo setData jest dla rekordu który istnieje

ja widzę to tak

  1.  
  2. $page = new TablePages();
  3. if(isset($_POST['id']) {
  4. $page->setData($_POST['id']);
  5. }
  6. $page->url = $_POST['url'];
  7. $page->save(); // insert lub update
  8.  
Go to the top of the page
+Quote Post
Pyton_000
post
Post #14





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


ihmo
  1. $page = new Page(12);
  2.  
  3. if(!$page)
  4. {
  5. // Insert
  6. $page->title = 'ala';
  7. $page->save();
  8. }
  9.  
  10. $page->title = 'Klocek';
  11. $page->save(); //Update
Go to the top of the page
+Quote Post
kayman
post
Post #15





Grupa: Zarejestrowani
Postów: 556
Pomógł: 40
Dołączył: 20.07.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


dzięki panowie, wiem mniej więcej jak to przebudować by było "do ręki" i nie powielać kodu
Go to the top of the page
+Quote Post
Crozin
post
Post #16





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


1. Takie podejście, czyli tzw. ActiveRecord, jest raczej słabym rozwiązaniem. W Google znajdziesz więcej na ten temat.
2. Temat dotyczy na dobra sprawę ORM-a. Pomyśl nad wykorzystaniem Doctrine.

Ten post edytował Crozin 27.01.2015, 10:41:55
Go to the top of the page
+Quote Post
Pyton_000
post
Post #17





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Może też użyć lżejszego Eloquent z Laravela, ale nie proponowałem bo stwierdziłem że autor robi to dla sportu (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
kayman
post
Post #18





Grupa: Zarejestrowani
Postów: 556
Pomógł: 40
Dołączył: 20.07.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


nie mam nic przeciwko ORM z prawdziwego zdarzenia jak Doctrine, Propel, chciałam sprawę uprościć na własne potrzeby a przy okazji czegoś się nauczyć

mam wrażenie, że deklaracja klasy odpowiadającej za obsługę jakiejś tabeli w bazie nie wyszła najgorzej a przy wykorzystaniu trait będzie w miarę szybka do napisania i w miarę czytelna
Go to the top of the page
+Quote Post
Pyton_000
post
Post #19





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


W Twoim Przypadku Trait nie jest potrzebny Bo:
- i tak nigdzie go nie wykorzystasz więcej niż w tych Modelach
- Musisz dołączać Trait i Interface

Lepiej już:
- Zostawić interface
- Zrobić klasę DbModel implementującą interfejs
- Dziedziczyć po DbModel

A jeszcze lepiej to dziedziczyć po Fabryce Model dzięki czemu będziesz mógł w bardzo szybki sposób zmienić implementację z BD na File np.
Go to the top of the page
+Quote Post
kayman
post
Post #20





Grupa: Zarejestrowani
Postów: 556
Pomógł: 40
Dołączył: 20.07.2012
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Pyton masz racje tylko w ten sposób zaraz napiszę kombajn a nie uproszczę całość a w takim wypadku już chyba lepiej skorzystać z gotowego rozwiązania bo szkoda czasu

btw. inteface można by chyba wywalić stosując trait bo metody i tak są w trait te co potrzeba
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 14:54