Jump to content
php.lv forumi

wintermute

Reģistrētie lietotāji
  • Posts

    144
  • Joined

  • Last visited

Posts posted by wintermute

  1. Es pamātā taisītu visu Core klasi ar statiskiem mainīgajiem un metodēm, jo nav vajadzīgas 2 Core klases instances. Tādā veidā tu jebkurā vietā varēsi papildus izsaukt Core::runController, tādā veidā radot HMVC paternu un tev nebūs jāglabā kaut kur papildus globāla Core klases instance.

     

    Ar ko īsti statiski mainīgies un funkcijas atšķiras no globāliem mainīgajiem no funkcijam iekš namespace ?

  2. Nu ja. Tu kā "WEB izstrādātājs" visu ko izperē sauc par MVC, jo ir taču tik kruti lietot MVC un visiem ir noteikt jālieto MVC.

    Bez MVC jau nu iztikt nekādi nevar.

     

    Tai pat laikā izskatās, ka tev nav ne mazākās nojausmas, kā tiek veidotas aplikācijas pēc nedaudz atšķirīgiem argitektūras principiem.

    Drošvien par MVVM vispār pirmo reizi padzirdēji lasot par backbone.js frameworku.

    FYI, server-side web framework'i, kuru reklamējas piesaucot MVC, lieto MVP un praktiski tikai ekskluzīvi šo pattern.

    CodeIgniter, CakePHP, Yii, Ruby on Rails, you name it.

  3. Intereseanti kā gan godājamais moderātors pie šāda secinājuma nonāca, es tiešām gribētu zināt kur viņš šadu informāciju izlasīja.

    Cik zinu ka Martins Fovlers tādas muļķības rakstījis nav?

     

    Parasti gan MVC elementu uzdevumi ir šādi :

    Model
    - domeina biznesa logika

    View
    - presentācijas loģika

    Controller
    - Model un View stāvoklā maiņa

    Tātad, tieši kāds kur ietilpst jēdzieni "lapa" un "elementu skaits lapā" ?

    "Lapa" ir tomēr, IMHO, koncepts kas iederās prezentācijas loģikā.

     

    Protams šis viss sadalījums ir pieejams tikai tad, ja Model nav aizstāds vienkārši ar nespējīgu ORM un View nav kļuvis par sinonīmu templeitam.

     

    P.S. Visi php fremewokr'i, kuru aprakstos is svinīgi paziņots, ka viņi realizē MVC arhitektūru, melo. .

    Klasiskais smalltalk MVC nav web'ā realizējams ( un nē, MVC nav "stiepjams" jēdziens, sasaiste starp struktūrām ir ļoti precīzi definēta),

    jo Model un View is savā starpā saistīti caur Observer patternu. Tā vietā web'ā tiek pielietoti citi arhitektūras patterni:

     

    atšķiras no klasiskā MVC ar to, ka datu plūsma starp M un V ir apgriezta.

    View izsauc metodes uz Model un pats pieprasa datus.

    M un V savstarpēji komonicē caur VM. ViewModel funkcionē kā saskarne caur kuru View pieprasa datus no Model

    un atbild par reālās informācijas konvertēšanu formā, kas saprotama View.

    M un V savāstarpā nekomunicē, Presenter structūra veic pieprasījumus Model objektam,

    noformē datus un padod tos View. ( visizplatītākais starp php frameworkiem )

     

    P.P.S HMVC arhitektūrai patiesībā ir ļoti limitēts sakars ar MVC. Šī arhitektūra ir daudz ciešāk saistīta ar PAC principiem.

  4. Jap .. tad gad lapa nonāk browserī, php par t vairs nav atbildīgs.

    Jebkurā gadījumā jautājums nav īstajā kategorijā.

     

    Ja tu gribi nomainīt īslaicīgi tikai kaut kādu teksta fragmentu,

    tad to var izdarīt ar primitīvu javascript. Nāksies iemācīties to ..

     

    Jebkas vairāk būs tev par sarežģītu.

  5. Tādā gadījumā es veidot piekrasījumu kā vienu parametru :

    http://
    who.cares
    /controller/action/param1/param2/etc

     

    kuru, ja pieejams mod_rewrite vai tā analogs, pārraksta kā :

    http://
    who.cares
    /index.php
    /controller/action/param1/param2/etc

    un, jā, šitas strādā uz visiem browseriem .. tāds kā nabagu
    url.rewrite

     

    Šitāda linka saturs parādīsies iekš $_SERVER['PATH_INFO'], kuru pēc tam tu caur vienu vai vairākiem preg_match().

    Ja tu izmantosi switch priekš šādām operācijām , tad to iegūsi ļoti lielu un praktiski nenotestējamu koda gabalu.

  6. Izdrukā to rindu :

    print_r( "select a.*, b.nosaukums as raz,b.id as raz_id, DATE_FORMAT(j_until,'%d/%m/%Y') as pro_new from prod_apr a, razotaji b
    left join jaunumi j on j.j_proid=a.id where a.razotajs=b.id and grupa_id=".$row['id'].$tmp." order by ordnr " );

     

    Un iebaro pa tiešo SQL ( droši vien ka caur phpmyadmin ). Protams pirms tam noformē kveriju, lai vieglāk atrast kurā rindā ir kļūda.

  7. 1. izmantojot ENUM rodas situācija, ka dati atrodas tabulas shēmā.

    2. ENUM kolonās dati tiek definēti kā string's, bet glabāti kā skaitlis.

    3. vērtības ENUM kolonā ir piesaistītas secībai, kurā tu tās definēji

    4. pievienojot jaunu variantu, ir jāatkārto visas iepriekš esošās vērtības precīzi tādā pašā secībā

    5. ja tu vairs neizmanto kādu vērtību, tā tik un tā ir jāatkārto pie katras tabulas alterācijas

     

    Tām vērtībam būtu jābūt citā tabulā un piesaistītām caur FOREIGN KEY.

  8. Vai arī uzliec JS, kas reizi minūtē ( 2ās , 5ās , whatever ) "pingo" serveri + tas ko briedis teica.

    Tad tu redzēsi kā online arī tos cilvēkus, kuri vienkārši lapu tur tab'ā atvērtu.

  9. Interesanti kāds gan tam sakars ar jQuery ?!?

     

    Nu kas tur ko nesaprast ?

    <!DOCTYPE html>
    <html>
      <head>		
         <meta charset=utf-8 />
         <title>Empty</title>
      </head>
      <body>
         <div class="header">
            <h1><a href="/">Empty</a></h1>
         </div>
         <div class="base">
            <ul class="panel">
               <li>..</li>
               <li>..</li>
               ..
            </ul>
            <ul class="other panel">
               ..
            </ul>
            <div class="main"></div>
         </div>
         <div class="footer">
         </div>
      </body>
    </html>
    

     

    Thats about it.

    Tālāk atliek tikai "sakrāsot" un pielikt apaļus stūrus kur vajag.

  10. Uz php 4.x file_get_contents() funkcijai bija tikai 2vi parametri.

     

    Ja tavs hostings joprojam tup uz 4.x versijas, tad maini hostingu.

    Tas nozīmē, ka pēdējo reizi viņī serveri konfigurējuši 2007ajā,

    jo tad tika pārtraukts php 4.x supports.

     

    Šobrīd vienīgā support'ētā php versija ir 5.3.x

  11. Un atkārtošos... parādi Man, wintermute, reālu "framework'u", kad dara visu tā, kā Tev patīk? Nu pēc Wikipedia's definīcijām. Un tad, lūdzu, pastāsti ieguvumus tam. Ātrdarbība? Mazāk kods? Nedomāju viss.

    Ja es atradīšu tādu , noteikti padalīšos.

     

    Bet vai tev tiešām liekas, ka tādi jēdzieni kā "loose coupling" in SOLID principi,

    tika izdomāti tāpēc, lai kods kļūtu lēnāks un grūtāk uzturams ?

  12. Problēma rodas tur, ka pie katra objekta veidošansa tev viņam būs jānodod daudz parametru.

    Nu neērti un nepārskatāmi ir katram modelim nodod db, memcahced, utt. instances.

     

    Kāda jēga no lieka rakstīt:

    $db=DBFactory::dod_shurp_db_instani();
    $memcahced=DBFactory::dod_shurp_memcahced_instanci();
    $user = new User($db,$memcahced,123);

     

    Lai tā vietā rakstītu:

    $user=User(123);

    un modeļi db piekļūs caur globāli pieejamu factory.

     

    Kurš tev teica ka tā vajag rakstīt ?

     

    Tas ko es parakstīju izskatītos apmēram šitā :

     

    //--------------------------------------
    // fails  userfactory.php
    
    class UserFactory implements UserBuilder
    {
      protected $_db;
      protected $_cache;
      protected $_id = null ;
    
      public function __construct( PDO $db , Cache $cache = null )
      {
         $this->_db = $db;
         $this->_cache = $cache;
      }
      public function set_id( $id )
      {
         $this->_id( $id )
      }
      public function build()
      {
          return new User( $this->_id , $this->_db , $this->_cache );
          // tas , vai ID tiek resetot''s vai nē ir gaumes (un dokumentācijas) jautājums
      }
    
    }

    //--------------------------------------
    // fails bootstrap.php
    
    $db = new PDO('sqlite::memory:');
    $mc = new Memcached('cache');
    $mc->addServers(array(
        array('mc1.example.com',11211),
        array('mc2.example.com',11211)
    ));
    
    $factory = new UserFactory( $db , $mc );
    
    $foo = new Foo( $factory );
    $foo->bar();
    
    

    //--------------------------------------
    // fails foo.php
    
    class Foo
    {
      protected $_factory;
    
      public function __construct( UserBuilder $factory )
      {
         $this->_factory = $factory;
      }
      public function bar()
      {
         $user = $this->factory->set_id(123)->build();
         /*
         $user3 = $this->factory->set_id(3243)->build();
         $Arthur = $this->factory->set_id(42)->build();
         */
      }
    
    }
    

     

    Tieši kur ir problēma ?

    Tagad, ja tev vajag pamainīt to kādu no elementiem,

    tad tev vairs nav jāpārraksta metode bar().

     

    Un ja tu gribi izveidot unit-testu priekš klases Foo,

    tu vari mierīgi aizstāt ar mock-objektiem DB un Cache,

    vai pat visu UserFactory, ja ir luste.

     

     

     

    Patiesībā jā. Ja tev datu modeļa pamatruktūra ir būvēta kā Strategy paterns un tu vari CRUD algoritmus nodot kā atsevišķas strategy klases. Kāpēc ne?

    Taču jāskatās vai visas nepieciešamo modeļa funkcionalitāte spēs nodrošināt katrs no algoritmiem: mysql, xml fails, web-serviss.

     

    Modeļi var būt būvēti uz dažādiem paterniem un katrs no tiem strādās savādāk. Modelis nav ORM, bet ORM ir modelis.

    Pie tam veidojot modeli, ir spēcīgi jāņem vērā arī tas, kā fiziski glabās datus, jo vienā veidā modeli varēs uzbūvēt, bet citā veidā teorētiski nebūs iespējams veikt kaut kādu funkcionalitāti, kā pirmajā gadījumā, un modeli nebūs iespējams uzbūvēt.

     

    Nē tā nav. Modelis atbild nevis par "datu loģiku" bet gan par "domeina biznesa loģiku".

    Tam nav nekāda sakar ar to kā un kur tu tos datus glabā.

    Produkta X daudzums noliktavā nav atkarīgs no tā, vai dati par to nāk no web-servisa, datubāzes vai xml.

     

    Tāpēc arī ORM nav modelis. Tās ir divas pilnīgi neatkarīgas struktūras.

     

     

     

     

    Nevienmēr, tikpat labi tas var būt jāizlemj kontrolerim. Pat šādā elmentārā situācijā, paziņojumu, ka nav naudas, var veidot kā atsevišķu view-u

    Bet ko darīsi, ka modeļa datu apstrādē ieviesīsies kļūda un vajadzēs padot citu view-u (kļūdu paziņojumu)? Tas jāizlemj kontrolerim.

     

    Nu nav tā.

    Kontrolerim ir jāsaņem un jāapstrādā dati no modeļa:

    - Ja lietotājs nav ielogojies, mainam view-u vai redirektojam.

    - Ja lietotājs nav pieeja sadaļai, mainam view-u.

    - Tāpat apskatot konkrēto lapu, mēs varam gribēt skaitīt lapas sadaļas unikālos apskatījumus. Šādā gadījumā kontrolerim vajadzēs iegūt datus par lietotāju, par konkrēto sadaļu, apstrādāt un nosūtīt šos datus apskatījumu modelim.

    Liekas problēma ir faktā, ka tu ar jēdzienu View saproti kaut ko pavisam citu.

    View nav "stulbs" template's, bet gan pilnvērtīga klase, kas darbojas ar vairākiem templatiem.

    class DocumentView extends View implements Renderable
    {
      public function render()
      {
         $factory = $this->_template-factory;
         try
         {
            $document = $this->library->get_document();
            $template = $this->get_template('main');
            $template->bind( 'title' , $document->get_title() );
            $template->bind( 'content' , $document->get_content() );
         }
         catch( AuthorizationException $e )
         {
            $template = $this->get_template('error');
            $template->bind( 'content' , 'Unauthorized access, please stop that !' );
         }
    
         return $template->render();
      }
    }
    

    Un kontrolierī ir rakstīt apmēram kaut kas šitāds.

    class DocumentController extends Controller
    {
      protected _view_name = 'DocumentView';
      protected _view = null;
    
      public function get_document()
      {
         $factory = $this->_model_factory;
         $library = $factory->set_class( 'Library' )->build(); // set_class() atrgriež $this
    
         $this->_view->set_template('main' ,  'some/location/document.tpl');
         $this->_view->set_template('error' , 'maybe/different/location/baaaaad.tpl');
         $this->_view->bind( 'library' , $library );
    
         $library->select_document( $this->get_param('id') );
      }
    
    }

     

    Tas ir apmēram kā es saprotu MVC triādi.

    - model: atbild par biznesa loģiku

    - view: atbild par prezentācijas loģiku

    - controller: sasaista view are modeļiem , un padod tiem 'signalus', kuri maina view un modeļu stāvokli

     

     

    Tam es piekrītu, bet tu iepriekš strikti pateici, ka, ja ir boolean parametrs, tad kaut kas nav pareizi.

    Ne vienmēr boolean parametrs atdala divas funkcionalitātes.

    Bet tā jau arī ir , ka booleans atdala divas funkcionalitātes.

    Ja tev ir viena vērtība, tad tu dari lietu a , un ja tev ir otra vērtība,

    tad tu dari lietu b ( vai arī dari gan a gan b ).

  13. Piemērs, kur tu šo praksi nevari apiet.

    Datubāze. Tev ir divi objekti, kuri darbojas ar db. Nu netaisīsi tu katram savu konekciju tā viena iemesla dēļ, ka tad tu nevarēsi nodrošināt transakcijas.

    Nu tad tu katram no tiem objektiem konstruktorā padod vienu un to pašu DB klases objektu, kaut vai pliku PDO instanci.

    $db = new PDO('sqlite::memory:');
    $foo = new Foo( $db );
    $bar = new Bar( $db );
    
    $bar->do_stuff();
    
    $foo->set_blah('hitchhiker');
    echo $foo->get_towel();
    

    Kur tieši tev rodas problēma ?

    Ja tev kādā objektā vajag Factory'u, tad to to padod konstruktorā.

    Un ja tas objekts izmanto Cache'u, tad arī tas tiek padots konstruktorā.

     

    Ja tiek mainīt nosaukums kolonai, tad arī aplikācijā ar plikiem SQL, tev būs jāmaina visi SQL, kur izmanto šo kollonu. Tāda ir dzīve.

    Bez tam izmantojot ORM, kuros kollonas definē modeļa definīcijā, db tabulas pa tiešu vispār neaiztiek, tā vietā to dara tūļi, kuri modeļa definīciju pārnes uz db.

    Tiešām ? Ak tad modelis nav saistīts ar datubāzi. Tad tu gribi man teikt, ka es varu nemainot pašu modeli glabāt un saņemt datus no XML faila vai kāda web-servisa ?

    Un par kolonām .. emm .. modelim nav nekāda sakara ar to tu fiziski glabā datus. Modelis !== ORM. Blame RoR.

    ( .. gandrīz vai jādomā, ka vienīgā DB abstrakcijas arhitektūras pattern's, kuru tu zini, ir active-record )

     

     

    Par vienvirziena datu plūsmu, no modeļa, tikai uz view-u un no kontrolera tikai uz modeli.

    Praksē tas nav iespējams, jo kontrolerim gandrīz vienmēr būs nepieciešami dati no modeļa, lai veiktu tālākās darbības.

    Piemēram, tu nospied pogu pirkt. Kontrolerim ir jāpārbauda vai lietotājam pietiek nauda (no user modeļa), jāpārbauda vai noliktavā ir prece (no storage modeļa), utt. un tikai tad, kad ir saņemti dati no vairākiem mopdeļiem, kontroleris var tālāk izlemt kādas darbības un izmaiņas veikt citos kontroleros un kādu view izsaukt.

    Ko darīt ar pirkumu, ja lietotājam nav naudas, izlemj modelis.

    Kā attēlot lietotājam, ka viņam nav naudas, izlemj view.

    Kontrolieris vienkārši padod lietotāja ievaddatus un modeli(-ļus) pie view.

     

     

     

    Kas tas par murgu? Jebkuru darbu var sadalīt smalkāk - jebkuru funkcionalitāti var sadalīt smalkāk.

    Tāpēc tāds jēdziens kā viena funkcija ir absurds.

    Metodei jāpilda tāda funkcionalitēte, kuru loģiskā veidā var atdalīt no pārējā un katrs gadījums ir individuāls.

    Pietam, viena metode var saturēt algoritmu, kurš izmanto vairākas citas metodes - bez tā nav iespējams iztikt.

    Pēc tavas šīs filozofijas, nav nemaz iespējams būvēt normālus aplikācijas abstrakcijas slāņus.

    Šķiet vakar pa nakti neizdevās normāli domu noformulēt :

    katra metode atbild par vienu noteiktu, viegli noformolējamu darbību.

    class TaskManager
    {
       function complete_task( $task , $user )
       {
           $task->mark_completed( $user );
           if ( $this->has_more_tasks( $user ) )
           {
               $new_task = $this->get_next_task( $user );
               $this->assign_task( $new_task , $user )
           }
       }
    }
    

    Kodā metodei ir viens pienākums ( uzdevums , funkcija ) un tev nevajag pusstundu pērties pa kodu,

    lai saprastu ko tā metode dara.

     

     

     

     

    Un ko darīsi, ja būs int parametrs ar iespējamām 5 vērtībām? Taisīsi 5 funkcijas.

    Pietiek murgot. Sāc domāt.

    Ja tev ir funkcija, kas dara 5 dažādas lietas, atkarībā no kaut kāda mistiska flag'a vērtības,

    tad tev pilnīgi noteikti būtu jābūt 5ām funkcijām.

    Un ja tev klasē it divas+ funkcijas, kam tādu flag'u vajag,

    tad optimālāk būtu izmantot polimorfismu un sadalīt to objektu pa 5ciem jauniem objektiem,

    kuri implementē vienu un to pašu interfeisu

×
×
  • Create New...