CodeIgniter er et enkelt og kraftig open source webapplikasjonsramme for PHP. I dag skal vi gjøre noen kjerne "hacks" til dette rammeverket for å endre og forbedre funksjonaliteten. I prosessen får du en bedre forståelse av intricacies av CodeIgniter.
På venstre side ser du den vanlige måten å laste inn en modell i CodeIgniter, fra en Controller. Etter denne hacken vil vi kunne lage objekter direkte. Koden er renere, og din IDE vil kunne gjenkjenne gjenstandstyper. Dette gjør det mulig for IDE-funksjoner som automatisk fullføring eller forhåndsvisning av dokumentasjon.
Det er to flere bivirkninger av denne hacken. For det første er du ikke lenger pålagt å utvide modellklassen:
Og du trenger ikke lenger å legge til et krav før du gjør modellklasse arv.
Alt vi trenger å gjøre er å legge til en PHP 5-stil autoloader-funksjon.
Legg denne koden til bunnen av systemet / application / config / config.php:
Hvis du er interessert i å bruke denne hacken til kontroller også, kan du bruke denne koden i stedet:
Når du prøver å bruke en klasse som ikke er definert, kalles denne __autoload-funksjonen først. Det tar vare på å laste inn klassefilen.
Normalt kan du ikke ha samme klassenavn for en modell og en kontroller. La oss si at du opprettet et modellnavn Post:
klassepost utvider modell // ...
Nå kan du ikke ha en nettadresse slik:
http://www.mysite.com/post/display/13
Årsaken er at det vil kreve at du også har en Controller-klasse som heter 'Innlegg'. Å opprette en slik klasse vil resultere i en dødelig PHP-feil.
Men med denne hack blir det mulig. Og kontrolløren for nettadressen vil se slik ut:
// søknad / kontroller / post.php klasse Post_controller utvider Controller // ...
Legg merke til '_controller'-suffikset.
For å omgå dette problemet, legger vanligvis folk flest «_model» -seksemplet til modellklasse-navnene (f.eks. Post_model). Modellobjekter blir opprettet og referert over hele applikasjonen, så det kan virke litt dumt å ha alle disse navnene med '_model' flytende rundt. Jeg synes det er bedre å legge til et suffiks til kontrollørene i stedet, siden de nesten aldri er henvist til deres klassenavn i koden din.
Først må vi utvide ruterklassen. Opprett denne filen: "application / libraries / MY_Router.php"
klassen MY_Router strekker seg CI_Router var $ suffix = '_controller'; funksjon MY_Router () foreldre :: CI_Router (); funksjon set_class ($ klasse) $ this-> class = $ class. $ Dette-> suffiks; funksjonen controller_name () if (strstr ($ this-> class, $ this-> suffiks)) return str_replace ($ this-> suffiks, ", $ this-> class); annet return $ this-> klasse;
Rediger nå "system / codeigniter / CodeIgniter.php" linje 153:
hvis (! file_exists (APPPATH.'controllers /'.$ RTR-> fetch_directory (). $ RTR-> controller_name (). EXT))
Samme fil, linje 158:
omfatte (APPPATH.'controllers /'.$ RTR-> fetch_directory () $ RTR-> controller_name () EXT..);
Deretter redigerer: "system / libraries / profiler.php", linje 323:
$ output. = ""$ Dette-> KI> router-> controller_name (). "/". $ Dette-> KI> router-> fetch_method ()."";
Det er alt. Husk at med denne hacken er du pålagt å sette '_controller'-suffikset på alle klassenavnene dine. Men ikke i filnavnene eller nettadressen.
CodeIgniter har en fin Form_validation klasse. Den følger med flere valideringsregler:
Disse er nyttige, men det mangler en viktig fra denne listen: å se etter unike verdier. For eksempel må de fleste brukerregistreringsskjemaer kontrollere at brukernavnet ikke allerede er tatt, eller at e-postadressen ikke allerede er i systemet.
Med denne hacken, vil du kunne legge denne valideringsregelen til skjemainnleggshåndtereren din veldig enkelt:
$ this-> form_validation-> set_rules ('brukernavn', 'Brukernavn', 'obligatorisk | alpha_numeric | min_length [6] | unikt [User.username]');
Legg merke til den siste delen som sier "unikt [User.username]." Denne nye valideringsregelen kalles bare "unik", og tar en parameter inne i firkant parentes, som er "tablename.fieldname". Så det vil sjekke kolonnen "brukernavn" i "Bruker" -tabellen for å forsikre deg om at innsendt verdi ikke allerede eksisterer.
På samme måte kan du sjekke for dupliserte e-postmeldinger:
$ this-> form_validation-> set_rules ('email', 'E-mail', 'required | valid_email | unique [User.email]');
Og søknaden din kan svare med riktige feilmeldinger:
Dette kan betraktes som mer av en utvidelse enn en hack. Likevel skal vi ta et kjerne CodeIgniter-bibliotek og forbedre det.
Opprett: "søknad / biblioteker / MY_Form_validation.php"
klasse MY_Form_validation utvider CI_Form_validation funksjon unik ($ verdi, $ params) $ CI = & get_instance (); $ KI> last> database (); $ CI-> form_validation-> set_message ('unique', 'Den% s brukes allerede.'); liste ($ tabell, $ felt) = eksplodere (".", $ params, 2); $ query = $ CI-> db-> velg ($ field) -> fra ($ table) -> hvor ($ field, $ value) -> limit (1) -> get (); hvis ($ spørring-> rad ()) return false; ellers return true;
Nå kan du bruke den unike valideringsregelen.
Akkurat som tittelen sier, er målet vårt å kunne kjøre CodeIgniter-applikasjoner fra kommandolinjen. Dette er nødvendig for å bygge cron-jobber, eller kjøre mer intensive operasjoner, slik at du ikke har ressursbegrensningene til et web-skript, for eksempel maksimal kjøretid.
Slik ser det ut på min lokale Windows-maskin:
Koden ovenfor vil være som å kalle denne nettadressen:
http://www.mysite.com/hello/world/foo
Opprett en "cli.php" -fil ved roten til CodeIgniter-mappen din:
hvis (isset ($ _ SERVER ['REMOTE_ADDR'])) die ('Bare kommandolinje!'); set_time_limit (0); $ _SERVER ['PATH_INFO'] = $ _SERVER ['REQUEST_URI'] = $ argv [1]; krever dirname (__ FILE__). '/Index.php';
Hvis du er i et Linux-miljø og ønsker å gjøre dette skriptet selvkrevbart, kan du legge til dette som første linje i cli.php:
#! / Usr / bin / php
Hvis du vil at en bestemt kontroller bare skal være kommandolinje, kan du blokkere websamtaler på kontrollerkonstruktøren:
klassen Hello utvider kontrolleren funksjon __construct () hvis (isset ($ _ SERVER ['REMOTE_ADDR'])) die ('Bare kommandolinje!'); foreldre :: Controller (); // //
Læren er et populært objektrelasjonsmapper for PHP. Ved å legge den til CodeIgniter, kan du ha et veldig kraftig modelllag i rammen.
Bare å installere Doctrine er ikke veldig "hacky" per se, da vi bare kan legge den til som en plugin. Men når du har lagt til, må modellklassene dine forlenge lærdomsklassene, i stedet for CodeIgniter Model-klassen. Dette vil helt endre måten Model laget fungerer i rammen. Objektene du oppretter, vil ha databasepåståelse og vil også kunne ha databaseforhold med andre objekter.
Følg disse instruksjonene:
// system / søknad / plugins / doctrine_pi.php // load Lærebiblioteket krever_once APPPATH. '/ plugins / doctrine / lib / Doctrine.php'; // last database konfigurasjon fra CodeIgniter require_once APPPATH. '/ config / database.php'; // dette vil tillate Lære å laste modellklasser automatisk spl_autoload_register (array ('Doctrine', 'autoload')); // vi laster inn våre databasetilkoblinger til Doctrine_Manager // denne sløyfen tillater oss å bruke flere tilkoblinger senere på forhånd ($ db som $ connection_name => $ db_values) // først må vi konvertere til dsn format $ dsn = $ db [$ connection_name] ['dbdriver']. ': //'. $ db [$ connection_name] ['brukernavn']. ':'. $ Db [$ connection_name] [ 'passord']. '@'. $ db [$ tilkoblingsnavn] ['vertsnavn']. '/'. $ Db [$ connection_name] [ 'database']; Doctrine_Manager :: tilkobling ($ DSN, $ connection_name); // CodeIgniter modell klasse må lastes require_once BASEPATH. '/ Libraries / Model.php'; // fortelle Lære hvor våre modeller er plassert Lære :: loadModels (APPPATH. '/ models');
Deretter redigerer "application / config / autoload.php" for å autoload dette doktrin plugin
$ autoload ['plugin'] = array ('doktrin');
Pass også på at du har databasekonfigurasjonen i "application / config / database.php".
Det er alt. Nå kan du lage lærmodeller i CodeIgniter-programmet. Les mine opplæringsprogrammer om dette emnet for mer informasjon.
Denne hacken vil gjøre det mulig for deg å kjøre flere sider fra en enkelt installasjon av CodeIgniter. Hvert nettsted vil ha sin egen applikasjonsmappe, men de vil alle dele samme systemmappe.
Installer CodeIgniter hvor som helst på serveren. Det trenger ikke å være under en nettsidemappe. Ta deretter søkemappen ut av systemmappen. Og gjør ytterligere kopier av det, som vist i bildet ovenfor, for hvert nettsted du vil kjøre. Du kan plassere disse programmappene hvor som helst, som under hver enkelt nettsidemapper.
Kopier nå index.php-filen til roten til hver nettsidemappe, og rediger den som følger:
På linje 26 legger du hele banen til systemmappen:
$ system_folder = dirname (__ FILE__). '... / codeigniter / system';
På linje 43 legger du hele banen til programmappen:
$ application_folder = dirname (__ FILE__). '... / application_site1';
Nå kan du ha uavhengige nettsteder ved hjelp av separate applikasjonsmapper, men deler samme systemmappe.
Det er en lignende implementering i CodeIgniter brukerhåndboken du kan lese også.
Når du bruker Opplastingsbiblioteket i CodeIgniter, må du angi hvilke filtyper som er tillatt.
$ Dette-> last> bibliotek ( 'upload'); $ Dette-> upload-> set_allowed_types ( 'jpg | jpeg | gif | png | zip');
Hvis du ikke angir noen filtyper, vil du motta en feilmelding fra CodeIgniter: "Du har ikke angitt noen tillatte filtyper."
Så som standard er det ikke mulig å la alle filtyper lastes opp. Vi må gjøre liten hack for å komme seg rundt denne begrensningen. Deretter vil vi kunne tillate alle filtyper ved å sette den til '*'.
$ Dette-> last> bibliotek ( 'upload'); $ Dette-> upload-> set_allowed_types ( '*');
For denne hack skal vi endre opplastingsklassens oppførsel.
Opprett fil: søknad / biblioteker / My_Upload.php
klasse MY_Upload strekker seg CI_Upload function is_allowed_filetype () if (count ($ this-> allowed_types) == 0 ELLER! is_array ($ this-> allowed_types)) $ this-> set_error ('upload_no_file_types'); returnere FALSE; hvis (in_array ("*", $ this-> allowed_types)) return TRUE; $ image_types = array ('gif', 'jpg', 'jpeg', 'png', 'jpe'); foreach ($ this-> allowed_types as $ val) $ mime = $ this-> mimes_types (strtolower ($ val)); // Bilder får noen ekstra sjekker hvis (in_array ($ val, $ image_types)) if (getimagesize ($ this-> file_temp) === FALSE) return FALSE; hvis (is_array ($ mime)) if (in_array ($ this-> file_type, $ mime, TRUE)) return TRUE; else if ($ mime == $ this-> file_type) return TRUE; returnere FALSE;
Jeg håper noen av disse er nyttige for deg. Hvis ikke, er de fortsatt interessante å vite og kan hjelpe deg med å lære mer om de interne arbeidene til et rammeverk og noen av de kjente PHP-språkfunksjonene.
Hvis du vet noen andre kule hack eller modifikasjoner, gi oss beskjed i kommentarene. Takk skal du ha!
Klar til å ta dine ferdigheter til neste nivå, og begynne å dra nytte av dine skript og komponenter? Sjekk ut vår søsters markedsplass, CodeCanyon.