Ερώτηση αρχάριου για Zend framework.

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

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

Απάντηση
Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από Apostolis_38 » 22 Μαρ 2012 22:26

Καλησπέρα σε όλους.

Θέλω να φτιάξω το εξής project σε Zend framework με έναν controller και δύο views:
Μπαίνοντας στην αρχική σελίδα να εμφανίζεται ένα πεδίο καταχώρησεις e-mail και μια φόρμα file upload. Μετά με zend_form να γίνεται το validation κι αν το e-mail είναι έγκυρο να γίνεται το upload και ύστερα parse του αρχείου.

Με "δικό" μου κώδικα μπορώ άνετα να φτιάξω κάτι τέτοιο αλλά με zend τα βρίσκω σκούρα γιατί, αν και έχω διαβάσει το manual του framework, δεν μπορώ να καταλάβω πως δουλεύει στην πράξη ο "κύκλος" με τους controllers και τα views.

Φαντάζομαι οτι από το index θα πρέπει να καλώ τα views με το validation και το upload κι αυτά θα καλούν τον controller κάνοντας τις απαραίτητες ενέργειες.
Στην πράξη όμως πως γίνεται αυτό; Απλώς καλώντας τις αντίστοιχες class; Αν "πειράξω " το index πετάει μόνο σφάλματα.
Διάβασα και κάποια tutorials αλλά μάλλον με μπέρδεψαν περισσότερο γιατί εμπλέκουν ένα σωρό άχρηστα βήματα, folders, controllers κ.λ.π.

Μπορεί κάποιος να το εξηγήσει λίγο απλά ή να μου δείξει κάποιο πραγματικά απλό και κατανοητό tutorial;

tango
Δημοσιεύσεις: 123
Εγγραφή: 20 Σεπ 2011 05:32

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από tango » 23 Μαρ 2012 00:30

Πάρε ένα απλό και κατανοητό tutorial να καταλάβεις τι παίζει και ετοιμάσου να στρωθείς στην πρακτική εξάσκηση.

http://net.tutsplus.com/tutorials/php/z ... m-scratch/

Και μην ξαναδώ να ρωτήσεις πώς από το index θα "καλέσω τα views" :D

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από Apostolis_38 » 23 Μαρ 2012 00:42

Θένκ γιου μαν.
Θα το κοιτάξω.



Και δεν θα ξανακάνω άσχετες ερωτήσεις. :roll: :D

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από Apostolis_38 » 23 Μαρ 2012 01:20

Σόρρυ μαν, αλλά και πάλι δεν το πιάνω.

π.χ.
Εχω στο index ένα form που κάνει post την μεταβλητή email στη σελίδα process.phtml

Αν στη σελίδα αυτή πάω και γράψω το απλό

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

$email = $_POST["email"]; echo $email;
όλα δουλεύουν ρολόϊ.




Αν μπλέξω και το ProcessController.php και γράψω

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

public function processAction()	{ $this->view->email; }
και μετά στο process.phtml το

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

echo $this->email;
δε γίνεται τίποτα.

Πάλι μπλέχτηκα :evil:

Άβαταρ μέλους
nirvana
Δημοσιεύσεις: 241
Εγγραφή: 01 Σεπ 2005 18:28
Τοποθεσία: Αγ. Παρασκευή

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από nirvana » 23 Μαρ 2012 09:42

Αρχικά έχεις καταλάβει πώς δουλέυει όλη η φάση?
Όταν εσύ πατάς στο url, localhost/mysite/public/process/process τότε αρχικά εκτελείτε η action process του controller process. Εσύ κάνεις κάποια δουλειά εκεί, και στο τέλος συνήθως θέτεις κάποιες μεταβλητές που θα είναι visible στο view. Αμέσως μετά σου εμφανίζεται το view (το phtml αρχείο που θα βρίσκεται στον φάκελο application/views/scripts/process/process.phtml)

Αυτό που μπορείς να κάνεις, είναι στην φόρμα (που φαντάζομαι έχεις στο process.phtml) να έχει action="process" (την ίδια action). Ύστερα στον controller ελέγχεις αν έχεις post request. Αν ναι θέτεις το email το email post variable. Κάπως έτσι:

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

        $emailForm = new Application_Form_Email();
        $emailForm->setAction('process') 
                ->setMethod('post');

        $email = '';

        if ($this->getRequest()->isPost())
        {
            if($emailForm->isValid($this->getRequest()->getPost()))
            {
                $request = $this->getRequest();
                $email = $request->getParam('email');
            }
        }
        $this->view->emailForm = $emailForm;
        $this->view->email = $email;
Έχω υποθέσει ότι την φόρμα την φτιάχνεις με το zend form, όπως δείχνουν τα περισσότερα tutorials. Όταν πατάς πρώτη φορά το url εκτελεί τον controller χωρίς να μπαίνει μέσα στα if, οπότε θέτει το email κενό και θέτει και την φόρμα. Αν όμως κάνεις submit την φόρμα κάνει τα πάντα ( τα προηγούμενα + μπαίνει μέσα στο πρώτο if, και αν έχεις και validators (π.χ. για το email) και είναι σωστοί, μπαίνει και στο 2ο if).

Στο process.phtml κάνεις απλά

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

<?=$this->emailForm?>
<p>Dwsate email&#58; <?=this->email?>
Αν το κάνεις κάπως διαφορετικά ή μπερδεύεσαι πες το μπας και βοηθήσουμε. Δυστυχώς δεν έχω βρει κάποιο πολύ καλό βιβλίο/tutorial/documentation για αρχάριους. Το μόνο αξιόλογο που έχω βρεί είναι ένα e-book, αλλά πολύ advanced (δηλαδή και εγώ που έχω καταλάβει τα βασικά, δεν μπορώ να το ακολουθήσω).

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από Apostolis_38 » 23 Μαρ 2012 14:35

Κατ' αρχάς ευχαριστώ.

Θεωρητικά έχω καταλάβει το πως δουλεύει το σύστημα.
Στην πράξη όμως είναι λίγο διαφορετικά.
Στο συγκεκριμένο παράδειγμα ας πούμε, αν το κάνεις χωρίς το framework έχεις απλώς μια ή δύο σελίδες όπου στέλνεις τη μεταβλητή και μετά την χρησιμοποιείς.

Εδώ δεν έχω καταλάβει ποιά ακριβώς είναι η δουλειά που κάνει ο controller και ποιό μέρος του κώδικα πρέπει να εκτελεστεί εκεί.
Αν και τείνω να συμπεράνω οτι τα views υπάρχουν μόνο και μόνο για την εμφάνιση του αποτελέσματος του controller, αυτό που με μπερδεύει είναι οτι έχω δει παραδείγματα όπου και στο view εκτελείτε κώδικας.
Υποτίθεται οτι η λογική του θα έπρεπε να είναι σαν το smarty αλλά παρ' όλα αυτά δεν μου είναι τόσο ξεκάθαρο.

Θα κοιτάξω να βγάλω άκρη με το παράδειγμά σου.

Άβαταρ μέλους
ThyClub
Honorary Member
Δημοσιεύσεις: 5312
Εγγραφή: 17 Νοέμ 2003 00:21
Τοποθεσία: Hell's Kitchen
Επικοινωνία:

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από ThyClub » 23 Μαρ 2012 15:06

Το ήξερα ότι το MVC θα μπερδέψει πολύ κόσμο. Αν το σκεφτείς σαν MCV θα σου λυθούν αρκετές απορίες ;)

Άβαταρ μέλους
nirvana
Δημοσιεύσεις: 241
Εγγραφή: 01 Σεπ 2005 18:28
Τοποθεσία: Αγ. Παρασκευή

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από nirvana » 23 Μαρ 2012 15:21

Γενικά υπάρχουν 2 τεχνικές (ανεξαρτήτως framework) που συνήθως χρησιμοποιούνται. Και στις 2 το view πρέπει να είναι μόνο gui (καθαρή html. Η php χρεισημοποιήτε μόνο για εμφάνιση τών μεταβλητών, απλά if και απλά loop. Καθόλου λογική).
Οι τεχνικές είναι:

1) Fat controller, skinny model. Τα πάντα γίνονται στον controller, και στο model γίνονται πολύ απλές αλληλεπιδράσεις με την βαση δεδομένων.
2) Το αντίθετο. Ο controller λειτουργεί με πολύ απλό τρόπο, σαν τροχονόμος, και προωθεί τα δεδομένα από τα request του χρήστη, προς τα μοντέλα που κάνουν τα πάντα (ελέγχους, αλληλεπιδραση με την βάση δεδομένων και με αρχεία κ.λ.π).

Εγώ προσωπικά χρησιμοποιώ τον δεύτερο τρόπο. Εδώ αναφέρουν και το γιατί είναι καλύτερος τρόπος αυτός.

Επείσης σε ένα ωραίο e-book που έχει γράψει κάποιος developer του Ζend(δεν θυμάμαι όνομα) συμφωνούσε με την άποψη αυτή και προσέθετε ότι ο controller δεν είναι data police (άρα ούτε καν ο έλεγχος του input πρέπει να γίνεται εκεί).

Φυσικά αυτά όλα δεν έχουν πάρα πολύ σημασία αφού ο καθένας έχει την ελευθερία να κάνει αυτό που ο ίδιος πιστέυει ότι είναι καλύτερο. Εγώ όταν μάθαινα στην αρχή το zend χρησιμοποιούσα τον πρώτο τρόπο. Με αυτά που διάβασα κατά καιρούς πείστηκα ότι δεν έκανα καλα. :)

Άβαταρ μέλους
korgr
Honorary Member
Δημοσιεύσεις: 5067
Εγγραφή: 07 Οκτ 2008 18:30
Τοποθεσία: Corinth
Επικοινωνία:

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από korgr » 23 Μαρ 2012 16:38

Αποστόλη αν θες ακούς αυτή την συμβουλή!
Fat Controller αδερφέ!
To Model το μόνο που πρέπει να κάνει είναι να εκτελεί τις database εργασίες που ο Controller του διατάζει! Ακόμα και τα queries ο controller πρέπει να τα συντάσσει και να τα εκτελεί το Model. Γιατί τις περισσότερες φορές τα queries προκύπτουν δυναμικά ανάλογα το request. Στον controller του search πχ, θα γίνουν όλα τα if ώστε να κτιστεί το σωστό query. Δουλειά του model είναι να το εκτελέσει και να επιστρέψει τα data στον controller (που με την σειρά του θα τα διαθέσει στο view προς παρουσίαση)

Σου παραθέτω και τμήμα του κώδικα από controller του Odyssey που διαχειρίζεται την ενότητα "ΠΡΟΪΟΝΤΑ"
Δεν χρειάζεται να κατανοήσεις τα πάντα, απλά δες τα cases της switch ανάλογα το view και δες πως κτίζεται η $q (το query).
Όπου $db και $content = επικοινωνία με Model

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

$sectionCatType = $categories->getCategoryType&#40;$this->section&#41;;
switch &#40;$this->view&#41;&#123;
	
case "search"&#58;
case "list"&#58;
	 
	if&#40;$this->view == "search" && empty&#40;$submitSearch&#41;&#41; break;
	$catID = &#40;int&#41;$catID;
	$q="select distinct count&#40;$section.id&#41; as total  
	from $section, content_$section";
	if&#40;$sectionCatType == "selectList" && $catID&#41; $q.=", selectlists";
	$q.=" where $section.id=content_$section.mainID and $section.active=1 and content_$section.langID='$langID' ";
	if&#40;$catID&#41;&#123;
		$catName = $categories->getCategoryName&#40;$catID, "content_".$this->section."_categories", $langID&#41;;
		$rootCatID = $categories->getRoot&#40;$catID, $this->section."_categories"&#41;;
		$rootCatID = &#40;empty&#40;$rootCatID&#41;&#41; ? $catID &#58; $rootCatID;
		$rootCatName = $categories->getCategoryName&#40;$rootCatID, "content_".$this->section."_categories", $langID&#41;;
		$posY = $db->getRecord&#40;"select posY from ".$this->section."_categories where id = '$rootCatID'"&#41;->posY;
		if&#40;$sectionCatType == "selectMenu"&#41;&#123;
			 $q.="and $section.catID='$catID' ";
		&#125;
		if&#40;$sectionCatType == "selectList"&#41;&#123;
			$fieldID = $system->getFieldID&#40;"catID", $this->sectionID&#41;;
			$q.="and selectlists.sectionID='$this->sectionID' and selectlists.fieldID='$fieldID' and selectlists.itemID=$section.id and selectlists.optionID='$catID' ";
		&#125;		
	&#125;
	$producerID = $custom->getProducerID&#40;$keyword&#41;;
	if&#40;$producerID&#41; &#123;
		$subquery=" or $section.producer='$producerID' ";
	&#125;		
	if&#40;$keyword&#41; $q.="and &#40;content_$section.title like '%$keyword%' or content_$section.body like '%$keyword%'".$subquery."&#41; ";

	if&#40;$newproduct&#41; $q.="and $section.new_product=1 ";
	if&#40;$offer&#41; $q.="and $section.offer=1 ";
	$numOfAllItems = $db->getRecord&#40;$q&#41;->total;
	if&#40;!$numOfAllItems&#41; $messages->addError&#40;t&#40;"Δεν βρέθηκαν καταχωρημένες εγγραφές"&#41;&#41;;
	if&#40;$numOfAllItems&#41;&#123;
		$presults = $system->getPresults&#40;$this->section&#41;;
		$page = &#40;int&#41;$_GET&#91;'ppage'&#93;;
		$maxrows = $numOfAllItems;
		$page = &#40;$page > 0&#41; ? $page &#58; 1;
		$startrecord=&#40;$page * $presults&#41; - $presults;
		$startrecord=&#40;$startrecord < 0&#41; ? 0 &#58; $startrecord ;
		$q="select distinct $section.*, content_$section.title, content_$section.minitext from $section, content_$section";
		if&#40;$sectionCatType == "selectList" && $catID&#41; $q.=", selectlists";
		$q.=" where $section.id=content_$section.mainID and $section.active=1 and content_$section.langID='$langID' ";
		if&#40;$catID&#41;&#123;
			if&#40;$sectionCatType == "selectMenu"&#41;&#123;
				 $q.="and $section.catID='$catID' ";
			&#125;
			if&#40;$sectionCatType == "selectList"&#41;&#123;
				$fieldID = $system->getFieldID&#40;"catID", $this->sectionID&#41;;
				$q.="and selectlists.sectionID='$this->sectionID' and selectlists.fieldID='$fieldID' and selectlists.itemID=$section.id and selectlists.optionID='$catID' ";
			&#125;		
		&#125;
	/* in case of search */
	if&#40;$keyword&#41; $q.="and &#40;content_$section.title like '%$keyword%' or content_$section.body like '%$keyword%'".$subquery."&#41; ";	
	if&#40;$newproduct&#41; $q.="and $section.new_product=1 ";
	if&#40;$offer&#41; $q.="and $section.offer=1 ";	
	$q.=" order by $section.id desc LIMIT $startrecord, $presults";
	$items = $db->getRecords&#40;$q&#41;;
	&#125;	
	break;





case "basket"&#58;
	$uid = $_GET&#91;"uid"&#93;;
	if&#40;!is_array&#40;$uid&#41;&#41; $variables->getSafeVars&#40;array&#40;'uid'&#41;&#41;;
	if&#40;!count&#40;$uid&#41;&#41; break;
	$auth = new authentication&#40;false&#41;;
	$login = $auth->getLoginStatus&#40;&#41;;
	$sectionTable = $section;
	$basketTypeName = &#40;$login&#41; ? "basket" &#58; "session";
	$basketTypeID = $basket->getBasketTypeID&#40;$basketTypeName&#41;;	
	if&#40;is_array&#40;$uid&#41;&#41;&#123;
		if&#40;count&#40;$uid&#41;&#41;&#123;
			foreach&#40;$uid as $thisUID&#41;&#123;
				$record = $content->getContentByID&#40;$sectionTable, $thisUID, '*', '*', $langID&#41;;
				if&#40;count&#40;$record&#41;&#41;&#123; // υπαρκτό προϊόν
					if&#40;$action == "add"&#41;&#123;
						$basket->addToBasket&#40;$thisUID, $quantity, $sectionTable, $basketTypeName&#41;;
					&#125;
					if&#40;$action == "remove"&#41;&#123;
						$basket->removeFromBasket&#40;$thisUID, $sectionTable, $basketTypeID, $massDelete&#41;;
					&#125;
					if&#40;$action == "move"&#41;&#123;
						$basket->changeBasketType&#40;$thisUID, $basketTypeID&#41;;
					&#125;
				&#125;
			&#125;
			if&#40;$action == "move" && is_file&#40;"wishlist.php"&#41;&#41;&#123; // anyway no wish list in this site
				header&#40;"Location&#58;wishlist.php"&#41;;
				exit;
			&#125;
		&#125;	
	&#125;else&#123;
		if&#40;!$uid && $action&#41; $messages->addError&#40;t&#40;"Δεν προσδιορίσατε προϊόν"&#41;&#41;;
		if&#40;$uid && !$messages->hasErrors&#41;&#123;
			$quantity = &#40;$quantity&#41; ? $quantity &#58; 1;
			$record = $content->getContentByID&#40;$sectionTable, $uid, '*', '*', $langID&#41;;
			if&#40;count&#40;$record&#41;&#41;&#123; // υπαρκτό προϊόν
				if&#40;$action == "add"&#41;&#123;
					$basket->addToBasket&#40;$uid, $quantity, $sectionTable, $basketTypeName&#41;;
				&#125;
				if&#40;$action == "remove"&#41;&#123;
					$basket->removeFromBasket&#40;$uid, $sectionTable, $basketTypeID, $massDelete&#41;;
					unset&#40;$uid&#41;;
				&#125;
			&#125;
		&#125;
	&#125;
	
	if&#40;$action == "remove"&#41; unset&#40;$uid&#41;;
	$messages->importSessionMessages&#40;&#41;; // import any messages set by basket class	
	break;  
 



 
case "node"&#58;

	$id = &#40;int&#41;$id;
	$item = $content->getContentByID&#40;$this->section, $id, "*", "*", $langID&#41;;
	if&#40;!$item&#41; &#123;
		$messages->addError&#40;t&#40;"Η συγκεκριμένη εγγραφή δεν βρέθηκε"&#41;&#41;;
	&#125;else&#123;
		$catID = $item->catID;
		$catName = $categories->getCategoryName&#40;$catID, "content_".$this->section."_categories", $langID&#41;;
		$rootCatID = $categories->getRoot&#40;$catID, $this->section."_categories"&#41;;
		$rootCatID = &#40;empty&#40;$rootCatID&#41;&#41; ? $catID &#58; $rootCatID;
		$rootCatName = $categories->getCategoryName&#40;$rootCatID, "content_".$this->section."_categories", $langID&#41;;
		$posY = $db->getRecord&#40;"select posY from ".$this->section."_categories where id = '$rootCatID'"&#41;->posY;		
	&#125;
	break;
  
default&#58;
  
&#125;


Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από Apostolis_38 » 23 Μαρ 2012 21:09

Ευχαριστώ.

Θα τα κοιτάξω και τα δύο αν και αυτή τη στιγμή το fat μοντέλο μου φαίνεται αν μη τι άλλο πιο ξεκάθαρο και κατανοητό.

Ελπίζω... :D

gvre
Δημοσιεύσεις: 990
Εγγραφή: 14 Οκτ 2010 11:34
Τοποθεσία: Ηράκλειο Κρήτης
Επικοινωνία:

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από gvre » 24 Μαρ 2012 15:04

Θα σου προτείνω κι εγώ το 2 (fat model) για τους εξής λόγους:

1. Το business logic πρέπει να είναι μέσα στο model και όχι στον controller. Αυτό θα το εκτιμήσεις ιδιαιτέρως αν/όταν χρειαστεί να κάνεις refactoring.
2. Τα models σου πρέπει να είναι reusable και testable. Αύριο πχ μπορεί να χρειαστεί τη δουλειά που κάνεις μέσω του web interface να την κάνεις και σε κάποιο cronjob ή σε κάποια mobile εφαρμογή. Το μόνο που θα χρειαστεί να κάνεις είναι να φτιάξεις την επικοινωνία με το model.
3. Μπορεί το model σου να είναι στην πραγματικότητα ένα web service. Δεν έχει νόημα να στέλνεις sql queries σε web service.

Αν διαθέτεις μεγάλη ομάδα, μπορείς να μοιράσεις τις εργασίες σε διαφορετικά άτομα. Τα models συνήθως τα φτιάχνουν backend developers με γνώσεις πάνω σε βάσεις δεδομένων, optimizations, security κλπ.
Για τα υπόλοιπα δε χρειάζεται κάτι τέτοιο.

Συμβουλή: Μη γράψεις sql queries στους controllers και στα views. Αν το query σου περιέχει φίλτρα από επιλογές του χρήστη, μπορείς να τα περάσεις στο model μέσω ενός array (πχ. filters) και εκεί να γίνει το "χτίσιμό" του.

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από Apostolis_38 » 24 Μαρ 2012 20:40

Μέχρι να φτάσω στο σημείο να χρησιμοποιώ όλα αυτά που μου λέτε έχουμε καιρό.
Ενα απλό email validation και file uload θέλω να κάνω και ζορίζομαι. :D

tango
Δημοσιεύσεις: 123
Εγγραφή: 20 Σεπ 2011 05:32

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από tango » 25 Μαρ 2012 02:10

+1 σε όσα είπε ο gvre :)

@korgr:

Δες το strategy pattern και πέτα αυτά τα switch cases στο κάλαθι της ιστορίας ;)

@gvre:

PostgreSQL, όχι PostreSQL (ούτε Poustre :D) ;)

gvre
Δημοσιεύσεις: 990
Εγγραφή: 14 Οκτ 2010 11:34
Τοποθεσία: Ηράκλειο Κρήτης
Επικοινωνία:

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από gvre » 25 Μαρ 2012 09:30

tango έγραψε: @gvre:

PostgreSQL, όχι PostreSQL (ούτε Poustre :D) ;)
Fixed. Thanks :)

Άβαταρ μέλους
korgr
Honorary Member
Δημοσιεύσεις: 5067
Εγγραφή: 07 Οκτ 2008 18:30
Τοποθεσία: Corinth
Επικοινωνία:

Ερώτηση αρχάριου για Zend framework.

Δημοσίευση από korgr » 25 Μαρ 2012 10:37

tango έχεις κάνει κανένα php framework?
Κανένα cms μήπως?

Απάντηση

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

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

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