Kom ihåg mig?
Home Menu

Menu


PHP: require, dela upp funktioner?

 
Ämnesverktyg Visningsalternativ
Oläst 2012-09-11, 11:19 #1
youheardit youheardit är inte uppkopplad
Har WN som tidsfördriv
 
Reg.datum: Oct 2008
Inlägg: 1 168
youheardit youheardit är inte uppkopplad
Har WN som tidsfördriv
 
Reg.datum: Oct 2008
Inlägg: 1 168
Standard PHP: require, dela upp funktioner?

Hejsan, hade svårt att sätta rubrik så ursäkta det dåliga valet.

Har lite funderingar gällande import av filer i php (require, include osv).

Jag brukar bygga en "core" fil där jag har alla funktioner och klasser. Denna filen importeras i index.php oftast.

Men vore det inte bättre om man gjorde en fil/funktion eller klass? så man slipper importera onödiga funktioner som inte kommer till användning alltid.

Exempel: (denna filen ska skicka ett email genom en egengjord funktion)
PHP-kod:
require("send_mail.php"); //filen med send_mail(); funktionen och INGET annat!
send_mail("[email protected]"); 
istället för:
PHP-kod:
require("core.php"); //filen med ALLA funktioner till hemsidan
send_mail("[email protected]"); 
Tacksam för lite tips och tricks ha det!
youheardit är inte uppkopplad   Svara med citatSvara med citat
Oläst 2012-09-11, 11:43 #2
Clarence Clarence är inte uppkopplad
Administratör
 
Reg.datum: Jan 2003
Inlägg: 1 974
Clarence Clarence är inte uppkopplad
Administratör
 
Reg.datum: Jan 2003
Inlägg: 1 974
Mitt första tips är att titta på OOP. Chansen att send_mail()-funktionen går att återanvända till ditt nästa projekt utan att skriva om den och få underhålla den i två projekt är liten om den ser ut som nu. Nästa gång vill du ha andra headers, gå direkt mot smtp osv. Sen 5 projekt in märker du att din mail inte alltid kommer in, så du vill logga alla mail som skickas. Då har du 5 ställen att gå in och ändra på. Detta löser en bra OOP-struktur åt dig.

Och det är även det enkla svaret på din fråga. Använd autoloading och lägg dina funktioner i klasser. För en snabb övergång kan du skapa klasser som Mail och bara ha en statisk funktion sendMail() i den. Så fort du försöker anropa Mail::sendMail() så kommer filen med klassen Mail att laddas och du slipper både manuellt inkludera filerna innan anropet och du laddar mer än du behöver (efter du läst på om cohesion och coupling).

Normalt sett brukar man också döpa filerna och därmed klasserna på ett sätt som gör att katalogträdet blir lite lättare att hitta filerna i också, liksom du får förklarande klassnamn. T ex kan du använda _ för att dela in det som t ex Mail_Transport_Smtp som hämtas från include/Mail/Transport/Smtp.php. Eller så lägger du Smtp-klassen i namespacet Vendor-name/Mail/Transport och får ungefär samma sökväg. Titta gärna på standarden PSR-0 om du ska börja använda autoloading (https://github.com/php-fig/fig-stand...epted/PSR-0.md).
Clarence är inte uppkopplad   Svara med citatSvara med citat
Oläst 2012-09-11, 13:47 #3
coredevs avatar
coredev coredev är inte uppkopplad
Bara ett inlägg till!
 
Reg.datum: Sep 2007
Inlägg: 1 554
coredev coredev är inte uppkopplad
Bara ett inlägg till!
coredevs avatar
 
Reg.datum: Sep 2007
Inlägg: 1 554
Ett generellt tips är att du inte vill ha för många require / includes i PHP eftersom det faktiskt stjäl tid. Försök hålla nere antalet, men kapsla gärna samtidigt in liknande funktioner i olika enheter (filer kan vara rätt för dig denna gång, i ett nytt projekt bör du ta Clarences råd och kika på OOP).
coredev är inte uppkopplad   Svara med citatSvara med citat
Oläst 2012-09-11, 17:30 #4
Clarence Clarence är inte uppkopplad
Administratör
 
Reg.datum: Jan 2003
Inlägg: 1 974
Clarence Clarence är inte uppkopplad
Administratör
 
Reg.datum: Jan 2003
Inlägg: 1 974
Citat:
Ursprungligen postat av coredev Visa inlägg
Ett generellt tips är att du inte vill ha för många require / includes i PHP eftersom det faktiskt stjäl tid. Försök hålla nere antalet, men kapsla gärna samtidigt in liknande funktioner i olika enheter (filer kan vara rätt för dig denna gång, i ett nytt projekt bör du ta Clarences råd och kika på OOP).
Samtidigt som detta kan vara sant kan det också vara tvärtom beroende på hur stor del av de inkluderade filerna som _kanske_ behövs faktiskt behövs vid varje request.

However, utvecklartid är dyrare än några procentenheter prestanda. Så att strukturera koden så att den ger färre buggar, är lättare att underhålla och arbeta vidare med (läs high cohesion, loose coupling) är viktigare än hur filerna laddas.
Clarence är inte uppkopplad   Svara med citatSvara med citat
Oläst 2012-09-11, 22:39 #5
Björn Björn är inte uppkopplad
Har WN som tidsfördriv
 
Reg.datum: May 2004
Inlägg: 1 224
Björn Björn är inte uppkopplad
Har WN som tidsfördriv
 
Reg.datum: May 2004
Inlägg: 1 224
Citat:
Ursprungligen postat av Clarence Visa inlägg
Mitt första tips är att titta på OOP. Chansen att send_mail()-funktionen går att återanvända till ditt nästa projekt utan att skriva om den och få underhålla den i två projekt är liten om den ser ut som nu. Nästa gång vill du ha andra headers, gå direkt mot smtp osv. Sen 5 projekt in märker du att din mail inte alltid kommer in, så du vill logga alla mail som skickas. Då har du 5 ställen att gå in och ändra på. Detta löser en bra OOP-struktur åt dig.

Och det är även det enkla svaret på din fråga. Använd autoloading och lägg dina funktioner i klasser. För en snabb övergång kan du skapa klasser som Mail och bara ha en statisk funktion sendMail() i den. Så fort du försöker anropa Mail::sendMail() så kommer filen med klassen Mail att laddas och du slipper både manuellt inkludera filerna innan anropet och du laddar mer än du behöver (efter du läst på om cohesion och coupling).

Normalt sett brukar man också döpa filerna och därmed klasserna på ett sätt som gör att katalogträdet blir lite lättare att hitta filerna i också, liksom du får förklarande klassnamn. T ex kan du använda _ för att dela in det som t ex Mail_Transport_Smtp som hämtas från include/Mail/Transport/Smtp.php. Eller så lägger du Smtp-klassen i namespacet Vendor-name/Mail/Transport och får ungefär samma sökväg. Titta gärna på standarden PSR-0 om du ska börja använda autoloading (https://github.com/php-fig/fig-stand...epted/PSR-0.md).
Bra post, väl förklarat! Kan inte annat än hålla med.
Björn är inte uppkopplad   Svara med citatSvara med citat
Oläst 2012-09-11, 23:34 #6
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Om man väl använder require() så använd då require_once() i stället så laddas filen bara en gång....

Men annars tycker jag du helt ska glömma allt vad imperativa programspråk heter och göra som Clarence skriver att omedelbart gå över till Objektorienterad programmering (dvs OOP).
Conny Westh är inte uppkopplad   Svara med citatSvara med citat
Oläst 2012-09-12, 11:57 #7
tartareandesire tartareandesire är inte uppkopplad
Supermoderator
 
Reg.datum: Jan 2004
Inlägg: 11 585
tartareandesire tartareandesire är inte uppkopplad
Supermoderator
 
Reg.datum: Jan 2004
Inlägg: 11 585
Citat:
Ursprungligen postat av ConnyWesth Visa inlägg
Om man väl använder require() så använd då require_once() i stället så laddas filen bara en gång....
Är varje prestandaförbättring viktig så är require bättre.
__________________
Full-stack developer, free for smaller assignments
tartareandesire är inte uppkopplad   Svara med citatSvara med citat
Oläst 2012-09-13, 01:22 #8
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Citat:
Ursprungligen postat av tartareandesire Visa inlägg
Är varje prestandaförbättring viktig så är require bättre.
Det är ytterst sällan som prestandaoptimering är första fokus i användarinteraktiva applikationer.

Mer än 90-99 procent av datorns tid står den och väntar på att användaren ska utföra något, så att optimera användargränssnitt för hastighet är i normalfallet mindre viktigt (lägre prioriterat), det som däremot är viktigt att fokusera på är:

1) enkelhet att använda
2) eliminera felkällor vid utveckling
3) underlätta uppdatering/underhåll
4) Underlätta drift/administration

Punkt 3 och 4 ovan står normalt för 5/6 av totala kostnaden under ett systems livslängd.

Först om man upplever problem med prestanda kan man lägga ner tid på att optimera för hastighet. Optast behövs det inte alls hastightsoptimeras vid denna typ av applikationer.

Det är viktigt att man har en plan för vad man lägger ner kostnaden på för ett system.
Conny Westh är inte uppkopplad   Svara med citatSvara med citat
Oläst 2012-09-13, 05:00 #9
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Jag har testat lite OOP med PHP och autoloader som jag tänkte dela med mig av:

Först min testklass:

Kod:
<?php
// File: TestAutoloader.php
// Author: Conny Westh 2012-09-13
  require_once('/lib/autoloader.php');


  try 
  {
      print "Test av autoloader.php\n";
      $c1 = new MyClass1();
      $c2 = new MyClass2();
  } 
  catch (Exception $e) 
  {
      print $e->getMessage();
  }
?>

Kod:
<?php

  class MyClass1
   {
     public static function run() { print "MyClass1 Works just fine...\n"; }
   }

  $className = 'MyClass1';
   $className::run();

?>
Kod:
<?php

  class MyClass2
   {
     public static function run() { print "MyClass2 Works just fine...\n"; }
   }

  $className = 'MyClass2';
   $className::run();

?>



Autoloader-klassen kan man lägga i en underkatalog som lämpligtvid heter LIB:
Kod:
<?php
// File: autoloader.php
// Modified by Conny Westh 2012-09-13
 class autoloader 
{
 
    public static $loader;
 
    public static function init()
     {
         if (self::$loader == NULL)
             self::$loader = new self();
 
        return self::$loader;
     }
 
    public function __construct()
     {
         spl_autoload_register(array($this,'approot'));
         spl_autoload_register(array($this,'model'));
         spl_autoload_register(array($this,'helper'));
         spl_autoload_register(array($this,'controller'));
         spl_autoload_register(array($this,'library'));
     }
 
    public function approot($class)
     {
         set_include_path(get_include_path().PATH_SEPARATOR.'/');
         spl_autoload_extensions('.php');
         spl_autoload($class);
     }
 
    public function library($class)
     {
         set_include_path(get_include_path().PATH_SEPARATOR.'/lib/');
         spl_autoload_extensions('.php');
         spl_autoload($class);
     }
 
    public function controller($class)
     {
         $class = preg_replace('/_controller$/ui','',$class);
         
        set_include_path(get_include_path().PATH_SEPARATOR.'/controller/');
         spl_autoload_extensions('.php');
         spl_autoload($class);
     }
 
    public function model($class)
     {
         $class = preg_replace('/_model$/ui','',$class);
         
        set_include_path(get_include_path().PATH_SEPARATOR.'/model/');
         spl_autoload_extensions('.php');
         spl_autoload($class);
     }
 
    public function helper($class)
     {
         $class = preg_replace('/_helper$/ui','',$class);
 
        set_include_path(get_include_path().PATH_SEPARATOR.'/helper/');
         spl_autoload_extensions('.php');
         spl_autoload($class);
     }
 
}
 
//call
 autoloader::init();
 ?>
Conny Westh är inte uppkopplad   Svara med citatSvara med citat
Oläst 2012-09-13, 08:44 #10
Clarence Clarence är inte uppkopplad
Administratör
 
Reg.datum: Jan 2003
Inlägg: 1 974
Clarence Clarence är inte uppkopplad
Administratör
 
Reg.datum: Jan 2003
Inlägg: 1 974
Citat:
Ursprungligen postat av ConnyWesth Visa inlägg
Jag har testat lite OOP med PHP och autoloader som jag tänkte dela med mig av:

--- klippt ---
Jag skulle rekommendera dig att fundera på att följa standarder. Jag vet att PHP är rätt nytt för dig så du kanske inte känner till dom.

PSR-0 har blivit en väl vedertagen standard för autoloading. Den ger dig interopabilitet mellan annan välskriven kod. https://github.com/php-fig/fig-stand...epted/PSR-0.md

Vidare är en full include_path baserad autoloading långsam samt mer error-prone och svåröveriktlig då du faktiskt måste åt en server-variabel för att se hela dess innebörd. Projektet blir alltså beroende av någon utanför projektet i sig. De flesta välskrivna projekt som har använt detta tidigare har använt en classmap generator för att lättare kunna överblicka och få bättre prestanda.

En exempel-impementation av en bra skriven PSR-0 autoloader kan du se på https://gist.github.com/221634 . Den är fullt produktionsduglig och är skriven av några av de främsta PHP-profilerna (både Zends och Symfonys huvudutvecklare finns representerade t ex).

Angående din kommentar om require_once så blir den inte alls gällande när du har en väl skriven autoloader. Det finns då längre ingen anledning att köra _once-funktionerna då andra användandet av klassen inte kommer försöka inkludera filen igen. Så en _once ger dig då ENDAST dubbla stat calls helt utan fördelar.
Clarence är inte uppkopplad   Svara med citatSvara med citat
Svara


Aktiva användare som för närvarande tittar på det här ämnet: 1 (0 medlemmar och 1 gäster)
 

Regler för att posta
Du får inte posta nya ämnen
Du får inte posta svar
Du får inte posta bifogade filer
Du får inte redigera dina inlägg

BB-kod är
Smilies är
[IMG]-kod är
HTML-kod är av

Forumhopp


Alla tider är GMT +2. Klockan är nu 10:03.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson
 
Copyright © 2017