Δημιουργία Front Controller σε ΡΗΡ με χρήση mod_rewrite

Σε αυτή την περιοχή μπορείτε να βρείτε ή να αναζητήσετε πληροφορίες σχετικές με την PHP

Συντονιστές: WebDev Moderators, Super-Moderators, PHP Moderators

Απάντηση
Άβαταρ μέλους
_mentos_
Δημοσιεύσεις: 87
Εγγραφή: 20 Ιούλ 2005 21:57
Τοποθεσία: Βύρωνας
Επικοινωνία:

Δημιουργία Front Controller σε ΡΗΡ με χρήση mod_rewrite

Δημοσίευση από _mentos_ » 21 Ιούλ 2007 14:54

καλημέρα (αν και 1:30 η ώρα :Ρ),

έχω το εξής ερώτημα. Έστω ότι έχουμε φτιάξει όλα τα URLs μας να είναι SEO friendly, στο mod_rewrite όλοι οι περιορισμοί / συνθήκες κλπ όλα σωστά, και καταλήγουμε να έχουμε ένα URL της μορφής:

Κώδικας: Επιλογή όλων

http://wwws.mydomain.com/articles/technology/sample_tech_article
υπάρχει κανένας άλλος τρόπος εκτός από το $_SERVER['URI'] σε συνδυασμό με το τη explode για να παρσάρω το URL? Δηλαδή θα πρέπει να πάρω την τελευταία παράμετρο (sample_tech_article) και να ψάξω στη βάση για κάτι αντίστοιχο? Ακόμα έστω ότι το άρθρο έχει μία επικεφαλίδα σιδηρόδρομο την οποία την μετατρέπω, δηλαδή από:

This is John's article for: fast food, cookies etc.

σε:

this_is_Johns_article_for_fast_food_cookies_etc

κατά πόσο αυτό επιβαρύνει το request στον server όταν ψάχνω πχ στο πεδία "permalink" με όλο αυτό το string σε σύγκριση με το να ψάχνεις στη βάση ένα ID που έχει μικρότερο length.

εάν έχει κανείς κάποια links ή κάποια tips πάνω στο τι πρέπει να γίνει ή κάποια τεχνική ας τα ποστάρει μπας και βρούμε την υγειά μας :lol: :lol:

ευχαριστώ εκ των προτέρων :wink: 8)

Άβαταρ μέλους
cherouvim
Script Master
Δημοσιεύσεις: 3137
Εγγραφή: 13 Ιούλ 2005 22:56
Τοποθεσία: Athens, Greece
Επικοινωνία:

Δημιουργία Front Controller σε ΡΗΡ με χρήση mod_rewrite

Δημοσίευση από cherouvim » 21 Ιούλ 2007 16:21

Το ψάξιμο για text identifier μπορείς να το κάνεις πιο γρήγορο βάζοντας ένα index στο πεδίο "permalink".

Και να μη το βάλεις πάντως, ακόμα και 1000 άρθρα να έχει το site σου, είτε ψάξει για id=63 είτε για permalink='this_is_Johns_article_for_fast_food_cookies_etc', δεν θα καταλάβει διαφορά ο χρήστης. Το 99% του bottleneck θα βρίσκεται στη μεταφορά της σελίδας από το server στο χρήστη, και όχι στη κατασκευή αυτής.

Όσο για το frontcontroller, δεν κατάλαβα πια είναι η ερώτησή σου.

Άβαταρ μέλους
_mentos_
Δημοσιεύσεις: 87
Εγγραφή: 20 Ιούλ 2005 21:57
Τοποθεσία: Βύρωνας
Επικοινωνία:

Δημιουργία Front Controller σε ΡΗΡ με χρήση mod_rewrite

Δημοσίευση από _mentos_ » 21 Ιούλ 2007 16:34

tnx για τνη απάντηση.

αυτό που είπα για τον controller είναι το εξής... όταν έχεις ένα URL της μορφής

Κώδικας: Επιλογή όλων

http://domain.com/index.php?page=articles&category=technology&id=65
για να δώσεις στον controller input για το τι θα κάνεις το κάνεις με ένα $_GET. πχ

Κώδικας: Επιλογή όλων

if ($_GET['page'] == "articles") {
	if ($_GET['category] == "technology") {
		// kane auto
	} else {
		...
	}
} else if ( ... ) {
	// kane auto
} else {
	// kane auto
}
τώρα με το mod_rewrite λογικά δεν μπορείς με ένα $_GET['page' ] να πάρεις τη τιμή γιατί το URL δεν μπορεί να διαβαστεί με $_GET, οπότε κάπως θα πρέπει να σπάσεις το URL σου έτσι ώστε να το δώσεις στον controller. Έτσι αν πάρεις το URL και το το κάνεις explode με delimiter τον χαρακτήρα "/" το url σου μετατρέπεται σε ένα array της μορφής (όλα αυτά στο περίπου πάντα):

Κώδικας: Επιλογή όλων

$uri = array(
	0 => www.mydomain.com
	1 => articles
	2 => technology
	3 => sample_tech_article
	);
Έτσι μπορείς να πεις πχ στον controller ότι

Κώδικας: Επιλογή όλων

if ($uri[1] == "articles") {
	if ($uri[2] == "technology") {
		// kane auto
	} else {
		...
	}
} else if ( ... ) {
	// kane auto
} else {
	// kane auto
}
Αυτό που ρωτάω είναι αν υπάρχει κάποιος πιο έξυπνος τρόπος πέρα από αυτόν που να απλοποιεί κάπως την διαδικασία γιατί με το συγκεκριμένο τρόπο όταν έχεις πολλές παραμέτρους στο url μπορεί να προκύψουν λάθη κλπ

tnx :wink:

Άβαταρ μέλους
cherouvim
Script Master
Δημοσιεύσεις: 3137
Εγγραφή: 13 Ιούλ 2005 22:56
Τοποθεσία: Athens, Greece
Επικοινωνία:

Δημιουργία Front Controller σε ΡΗΡ με χρήση mod_rewrite

Δημοσίευση από cherouvim » 21 Ιούλ 2007 18:02

Ναι το ξέρω το pattern, απλά δεν είπες πιο είναι το πρόβλημά σου.

Στα php MVC apps μου, το index.php είναι το frontcontroller. Τα URLs τα περιμένει έτσι:

Κώδικας: Επιλογή όλων

index.php/articles/technology/sample_tech_article
index.php/various/photos
Μετά διαβάζω το $_SERVER["PATH_INFO"] που περιέχει το key "articles/technology/sample_tech_article".

Αυτό μου αρκεί για να χτυπήσω τη βάση και να φέρω το article. Το πρόγραμμα δεν διαφοροποιεί καθόλου το "articles/foo/bar" από το "various/photos" και το "about". Όλα είναι σελίδες. Η κατηγοριοποίηση γίνεται καθαρά για λόγους εμφάνισης και εικονικής ομαδοποίησης των σελίδων. Φυσικά μπορώ να πω "φέρε μου όλα τα pages κάτω από το articles/2005".

Μία δυσκολία με αυτή τη μέθοδο είναι οτι αν μία μέρα ο admin θέλει να μετονομάσει τα 100 άρθρα κάτω από το "articles/" σε "stories/" τότε πρέπει να αλλάξουν 100 keys.

Στη βάση η κάθε σελίδα έχει και ένα τύπο (page type), με δικά τις πεδία (για επιπλέον δεδομένα), object (για διαφορετική λογική) και template (για διαφορετική εμφάνιση).

Άβαταρ μέλους
_mentos_
Δημοσιεύσεις: 87
Εγγραφή: 20 Ιούλ 2005 21:57
Τοποθεσία: Βύρωνας
Επικοινωνία:

Δημιουργία Front Controller σε ΡΗΡ με χρήση mod_rewrite

Δημοσίευση από _mentos_ » 21 Ιούλ 2007 19:09

Μετά διαβάζω το $_SERVER["PATH_INFO"] που περιέχει το key "articles/technology/sample_tech_article".

Αυτό μου αρκεί για να χτυπήσω τη βάση και να φέρω το article. Το πρόγραμμα δεν διαφοροποιεί καθόλου το "articles/foo/bar" από το "various/photos" και το "about". Όλα είναι σελίδες. Η κατηγοριοποίηση γίνεται καθαρά για λόγους εμφάνισης και εικονικής ομαδοποίησης των σελίδων. Φυσικά μπορώ να πω "φέρε μου όλα τα pages κάτω από το articles/2005"
σε αυτό το σημείο προβληματίζομαι. πχ αν έχεις "articles/2005" που έστω ότι δείχνει το archive για τα άρθρα για το 2005 και έχεις και το "articles/technology" που δείχνει όλα τα άρθρα κάτω από την κατηγορία "technology" πως θα δώσεις στον controller να καταλάβει ότι η δεύτερη παράμετρος (δηλ. τα 2005 κ technology στην περίπτωση μας) διαφέρουν και ότι θα πρέπει να τρέξει άλλο query για το καθένα.

μετά αν έχεις "articles/technology/2005" ή "articles/2005/05" πως θα καταλάβει ο controller για το τι είναι το καθένα? Δηλαδή στην πρώτη περίπτωση πως θα πω του controller "κάνε ότι είναι να κάνεις για $_GET['page']==articles" από τη στιγμή που δεν υπάρχει το index.php?page=articles.

Ακόμα δοκίμασα το $_SERVER["PATH_INFO"] στον τοπικό μου server και δεν μου έβγαζε το key ενώ το $_SERVER["REQUEST_URI"] το εμφάνισε κανονικά.

Σχετικά με την βάση προτείνεις κάτι τέτοιο δηλαδή?

Εικόνα

στο πεδίο data θα καταχωρείται ο αντίστοιχος πίνακας με τις εξτρά πληροφορίες για κάθε τύπο σελίδας.

Sorry αν γίνομαι κουραστικός αλλά τώρα τελευταία άρχισα να ασχολούμαι με το MVC και τρώω κάτι σκαλώματα :roll: :lol: :lol:

thanx κ πάλι ;)

Άβαταρ μέλους
cherouvim
Script Master
Δημοσιεύσεις: 3137
Εγγραφή: 13 Ιούλ 2005 22:56
Τοποθεσία: Athens, Greece
Επικοινωνία:

Δημιουργία Front Controller σε ΡΗΡ με χρήση mod_rewrite

Δημοσίευση από cherouvim » 21 Ιούλ 2007 19:47

Υπάρχουν πολλοί τρόποι για να κατηγοριοποιήσεις τα δεδομένα σου. Ο τρόπος που σου είπα είναι μία 1 προς 1 σχέση μεταξύ key και σελίδας. Δεν υπάρχει άλλος τρόπος για να δεις μία σελίδα (όπως γίνεται στο wordpress ας πούμε).

Στο σχήμα που έδωσες υπάρχει πολύς πλεονασμός.
Δες αυτό:

Κώδικας: Επιλογή όλων

+----+--------+---------+----------------+---------------------+----------+-------+------+
| id | parent | type    | key            | created             | modified | title | body |
+----+--------+---------+----------------+---------------------+----------+-------+------+
|  1 | <NULL> | index   | /              | 2007-04-12 12&#58;34&#58;25 | ...      | ...   | ...  |
|  2 |      1 | simple  | /news          | 2007-04-12 12&#58;35&#58;20 | ...      | ...   | ...  |
|  3 |      2 | news    | /news/2006     | 2007-04-12 22&#58;36&#58;42 | ...      | ...   | ...  |
|  4 |      2 | news    | /news/2007     | 2007-04-14 12&#58;33&#58;53 | ...      | ...   | ...  |
|  5 |      2 | news    | /news/2008     | 2007-04-15 12&#58;33&#58;02 | ...      | ...   | ...  |
|  5 |      1 | sitemap | /sitemap       | 2007-04-15 10&#58;53&#58;31 | ...      | ...   | ...  |
|  6 |      1 | simple  | /about         | 2007-04-15 11&#58;23&#58;42 | ...      | ...   | ...  |
|  7 |      6 | contact | /about/contact | 2007-04-15 17&#58;36&#58;11 | ...      | ...   | ...  |
+----+--------+---------+----------------+---------------------+----------+-------+------+
Από αυτό προκύπτει η εξής δενδρική δομή:

Κώδικας: Επιλογή όλων

  /
  |
  +--/news
  |    |
  |    +--/news/2006
  |    |
  |    +--/news/2007
  |    |
  |    +--/news/2008
  |
  +--/sitemap
  |
  +--/about
       |
       +--/about/contact
Όταν ο χρήστης χτυπήσει το /news, το σύστημα θα φέρει το id 2 σε ένα assoc array και θα το ταΐσει στο constructor του NewsPage το οποίο έχει δικό του logic και template.
Το ContactPage ας πούμε, στο template του, μαζί με το title και body fields, εκτυπώνει μία φόρμα επικοινωνίας. Την οποία ξέρει πως να χειριστεί σε περίπτωση που γίνει submit.

Το σχήμα μπορείς να το εμπλουτίσεις με πεδία όπως createdBy (FK στο users table), modifiedBy (FK στο users table), state (draft, editing, live)

Αν θες να το προχωρήσεις, και να έχεις διαφορετικά extra πεδία για κάθε page type, διάβασε τα 3 Object-Relational Structural Patterns όπως τα έχει περιγράψει ο Martin Fowler.
http://www.martinfowler.com/eaaCatalog/ ... tance.html
http://www.martinfowler.com/eaaCatalog/ ... tance.html
http://www.martinfowler.com/eaaCatalog/ ... tance.html

υ.γ. Έτσι έχω στήσει αυτό το site: http://fruit.gr/

Άβαταρ μέλους
_mentos_
Δημοσιεύσεις: 87
Εγγραφή: 20 Ιούλ 2005 21:57
Τοποθεσία: Βύρωνας
Επικοινωνία:

Δημιουργία Front Controller σε ΡΗΡ με χρήση mod_rewrite

Δημοσίευση από _mentos_ » 24 Ιούλ 2007 02:49

το είχα δει το συγκεκριμένο site όταν το είχες ποστάρει στο VCDC πριν από λίγο καιρό. nice job ;)

σχετικά με την οργάνωση που της βάσης που προτείνεις, έκανα κάποιες σκέψεις και όλα καλά εκτός από το σημείο που μπαίνει το `key` και αυτό γιατί σκέψου την εξής περίπτωση. Θέλουμε να δίξουμε όλα τα άρθρα κάτω από την κατηγορία "tech" για την χρονιά 2007 και το μήνα 07. Μπορούμε μεν να τραβήξουμε όλα τα άρθρα με βάση το πεδίο `created` αλλά παράλληλα σκοπός είναι να δείχνουμε και τον τίτλο και την ημερομηνία στο date στο URL μας. με άλλα λόγια το URL μας θα είναι της μορφής:

Κώδικας: Επιλογή όλων

http&#58;//domain.com/articles/tech/2007/07/
και το λινκ για κάθε άρθρο που έχεις θα είναι της μορφής

Κώδικας: Επιλογή όλων

http&#58;//domain.com/articles/tech/2007/07/article_title
περνώντας με τον τρόπο που προτείνεις το `key` στη βάση αυτόματα χάνεις αυτή τη δυνατότητα γιατί δεν έχεις ευελιξία, αυτό που είπες και εσύ στην περίπτωση που θες να αλλάξεις κάτι. Έτσι θα καταλήξω ξανα στην αρχική μου ερώτηση η οποία ήταν διατυπωμένη λίγο χάλια. Πως θα κάνω το controller να διαβάζει μορφοποιημένα URLs μέσω της $_GET. Τελικά η λύση ήτνα πιο απλή από'τι φανταζόμουν. Γράφεις απλά μερικούς κανόνες στο mod_write του apache και κάνεις τη δουλεία σου. πχ

Κώδικας: Επιλογή όλων

RewriteEngine on
RewriteRule ^&#40;&#91;a-z0-9\_\-&#93;+&#41;/&#40;&#91;a-z0-9\_\-&#93;+&#41;/&#40;&#91;a-z0-9\_\-&#93;+&#41;&#40;&#91;/&#93;*&#41;$ /bootstrap.php?type=$1&cat=$2&id=$3 &#91;QSA,NC,L&#93;
άμα διαβάσεις ένα url της μορφής:

Κώδικας: Επιλογή όλων

http&#58;//domain.com/articles/tech/54
ο apache θα το μετατρέψει σε url της μορφής

Κώδικας: Επιλογή όλων

http&#58;//domain.com/bootstrap.php?type=articlescat=tech&id=54
oπότε δεν χρειάζεται να αλλάξεις κάτι στον κώδικα σου. Τώρα στην περίπτωση που θες να αλλάξεις κάτι δεν έχεις το πρόβλημα που είχες πριν που θα έπρεπε να αλλάξεις 100+ keys. Δηλαδή αν θες να αλάξεις την κατηγορία από tech σε technology δεν θα αλλάξεις τα 100+ άρθρα που έχουν καταχωρηθεί αρχικά με αυτό το key αλλά μόνο το key στη συγκεκριμένη κατηγορία ;)

Άβαταρ μέλους
cherouvim
Script Master
Δημοσιεύσεις: 3137
Εγγραφή: 13 Ιούλ 2005 22:56
Τοποθεσία: Athens, Greece
Επικοινωνία:

Δημιουργία Front Controller σε ΡΗΡ με χρήση mod_rewrite

Δημοσίευση από cherouvim » 24 Ιούλ 2007 09:10

Ναι. Ο τρόπος που σου έδειξα δεν παρέχει ευελιξία σε αυτό το θέμα.

Δεν χρειάζεται πάντως να μεταφέρεις τόση γνώση για τα URLs σου στον apache. Ο apache μπορεί απλά να μεταφράζει το ακόλουθο URL:

Κώδικας: Επιλογή όλων

http&#58;//domain.com/articles/tech/54
σε αυτό:

Κώδικας: Επιλογή όλων

http&#58;//domain.com/index.php/articles/tech/54
Με την PHP θα splitάρεις και θα αναθέσεις το κάθε token του URL στις μεταβλητές type, cat, id.

Γενικά, αν θέλεις ένα πιο σωστό τρόπο κατηγοριοποίησης, μπορείς να χρησιμοποιήσεις tags/keywords.

Κώδικας: Επιλογή όλων

+--------------+
|   keywords   |
+----+---------+
| id |  title  |
+----+---------+
|  1 | tech    |
|  2 | vista   |
|  3 | coding  |
|  4 | spam    |
|  5 | 2006    |
|  6 | 2007    |
|  7 | 2008    |
|  8 | php     |
|  9 | mysql   |
| 10 | news    |
+----+---------+

+----------------------+
|    page_keywords     |
+---------+------------+
| page_id | keyword_id |
+---------+------------+
|       1 |          1 |
|       1 |          5 |
|       1 |          8 |
|       2 |          1 |
|       2 |          7 |
|       3 |          9 |
|       3 |         10 |
|       5 |          2 |
|       5 |         10 |
|       6 |          4 |
+---------+------------+
Θα ρίχνεις tags στις σελίδες σου (σαν τα categories του W), και μετά θα μπορείς να κάνεις ένα σωρό κόλπα για searching, grouping κτλ.

Όσο για το created δεν είναι αυτή η χρήση του. Πρέπει να υπάρχει και ένα "publishedAt" για το πότε δημοσιεύθηκε το άρθρο/σελίδα. Ο content manager μπορεί να δημιουργήσει 5 articles την ίδια στιγμή, αλλά μέχρι να βγουν από το create/edit/publish workflow, να έχει περάσει καιρός. Ένα άλλο ωραίο feature είναι να μπορείς να θέτεις publishing date στο μέλλον, έτσι ώστε τα άρθρα να εμφανίζονται μόνα τους, όταν έρθει η ώρα.

Απάντηση

Επιστροφή στο “PHP Προγραμματισμός”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες