सादे PHP का उपयोग करके टेम्पलेट सिस्टम की संरचना कैसे करें?


15

मैं इस सवाल पर पढ़ रहा था stackoverflow पर:

/programming/104516/calling-php-functions-within-heredoc-strings

और स्वीकृत उत्तर इस तरह सादे PHP टेम्पलेट करने के लिए कहते हैं:

template.php:

<Html>
    <Head>
        <Title> <? = $ शीर्षक?> </ Title>
    </ Head>
    <Body>
        <? = GetContent ()?>
    </ Body>
</ Html>

index.php:

<? Php

$ शीर्षक = 'डेमो शीर्षक';

समारोह getContent () {
    वापसी '<p> हैलो वर्ल्ड! </ p>';
}

( 'Template.php') शामिल हैं;

?>

मेरे लिए ऊपर इस अर्थ में अच्छी तरह से संरचित नहीं है कि template.php अन्य स्क्रिप्ट में परिभाषित चर पर निर्भर करता है। और जब आप ऐसा include('template.php')करते हैं, तो एक वर्ग (या एक समारोह जिसमें तुरंत क्रियान्वित नहीं किया जाता है) को शामिल करने के लिए एक शामिल () कोड को निष्पादित करने के लिए () का उपयोग कर रहे हैं ।

मुझे लगता है कि एक फ़ंक्शन के अंदर अपने टेम्पलेट को लपेटने के लिए एक बेहतर दृष्टिकोण है:

template.php:

<? Php

समारोह टेम्पलेट ($ शीर्षक, $ सामग्री) {
    ob_start (); ?>

<Html>
    <Head>
        <Title> <? = $ शीर्षक?> </ Title>
    </ Head>
    <Body>
        <? = $ सामग्री?>
    </ Body>
</ Html>

    <; php वापसी ob_get_clean ();
}

?>

index.php:

<? Php

require_once ( 'template.php');

प्रिंट टेम्प्लेट ('डेमो टाइटल', '<p> हैलो वर्ल्ड! </ p>');

?>

क्या दूसरा दृष्टिकोण बेहतर है? वहाँ यह करने के लिए एक बेहतर तरीका है?

जवाबों:


12

मैं दूसरा दृष्टिकोण नहीं करूंगा क्योंकि पैरामीटर का नाम नहीं है।

यह वर्णन करने के बारे में एक अच्छी तरह से लिखा गया कि एक टेम्पलेट सिस्टम को कैसे काम करना चाहिए, यह Parr से आ रहा है, यह अक्सर टेम्पलेट सिस्टम और / या वेब-पीवीसी फ्रेमवर्क लिखने वाले लोगों द्वारा उद्धृत किया जाता है।

व्यक्तिगत रूप से, जो मैं आमतौर पर पसंद करता हूं वह है कि एक सरणी सरणी के साथ एक ArrayObject वर्ग को लागू करना, और टेम्पलेट को संदर्भित करेगा $this->propertyName, जो वास्तव में टेम्पलेट ऑब्जेक्ट होगा $this->property['name']। यह भी बस का उपयोग करके प्राप्त किया जा सकता है , __setऔर __get:

class Template {
  private $_scriptPath=TEMPLATE_PATH;//comes from config.php
  public $properties;
  public function setScriptPath($scriptPath){
    $this->_scriptPath=$scriptPath;
  }
  public function __construct(){
      $this->properties = array();
  }
  public function render($filename){

   ob_start();
   if(file_exists($this->_scriptPath.$filename)){
     include($this->_scriptPath.$filename);
    } else throw new TemplateNotFoundException();
    return ob_get_clean();
  }
  public function __set($k, $v){
      $this->properties[$k] = $v;
  }
  public function __get($k){
      return $this->properties[$k];
  }
}

और एक टेम्पलेट जैसा दिखेगा:

<html>
      <head>
         <title><?=$this->title?></title>
      </head>
      <body>Hey <?=$this->name?></body>
</html>

और इसे लागू करना ऐसा लगेगा:

$view = new Template();
$view->title="Hello World app";
$view->properties['name'] = "Jude";
echo $view->render('hello.inc');

जहाँ तक मुझे याद है, यह है कि पुराने सिम्फनी 1.x और Zend_View टेम्पलेट इंजन कैसा दिखता है, और मेरे लिए यह ठीक है।


TinyButStrong कुछ समान करता है, साथ ही
इज़काता

आप कुछ स्कोर पर लूपिंग को कैसे कहते हैं? क्या आप एक अलग "उप" टेम्पलेट का उपयोग करते हैं?
रयान

मुझे आश्चर्य है कि अगर टेम्पलेट में $ का उपयोग करने से छुटकारा पाने का कोई तरीका है, उदाहरण के लिए सिर्फ $ शीर्षक या $ नाम।
रयान

1
@Ryan आप extract($this->properties);विवरण शामिल करने से पहले, चर में गुण निकालने के लिए उपयोग कर सकते हैं ।
जॉयस बाबू

2

क्योंकि Codeigniter मेरा पसंदीदा ढांचा है, मैं आपको एक Codeigniter-ish समाधान प्रस्तावित करता हूँ:

class Template {
    protected $path, $data;

    public function __construct($path, $data = array()) {
        $this->path = $path;
        $this->data = $data;
    }

    public function render() {
        if(file_exists($this->path)){
            //Extracts vars to current view scope
            extract($this->data);

            //Starts output buffering
            ob_start();

            //Includes contents
            include $this->path;
            $buffer = ob_get_contents();
            @ob_end_clean();

            //Returns output buffer
            return $buffer;
        } else {
            //Throws exception
        }
    }       
}

आपका टेम्पलेट ऐसा दिखेगा:

<html>
    <head>
        <title><?=$title?></title>
    </head>
    <body>
        <?=$content?>
    </body>
</html>

और आप इसे क्लास को इंस्टेंट करके, एक कंस्ट्रक्टर पैरामीटर के रूप में एक सरणी में डेटा पास करके और 'रेंडर' विधि को कॉल करके प्रस्तुत करेंगे:

$data = array('title' => 'My title', 'content' => 'My content');
$tmpl = new Template('template.php', $data);
echo $tmpl->render();

इस तरह से आप सीधे शामिल कोड को निष्पादित नहीं कर रहे हैं, और आप अपने टेम्पलेट को पठनीय भी रख रहे हैं, इसलिए डिजाइनर खुश होंगे।


1

एक टेम्पलेट हमेशा बाहरी चर पर निर्भर करेगा , और PHP एक गतिशील भाषा होने के साथ, संकलन समय पर लागू करने का कोई तरीका नहीं है कि वे वहां होंगे। तो पहला दृष्टिकोण शायद ठीक है; हालांकि अभी भी कुछ समस्याएं हैं:

  • उदाहरण आउटपुट को HTML-एन्कोडिंग का ख्याल नहीं रखता है, जिसका अर्थ है कि आपके पास संभावित XSS कमजोरियां हैं।
  • यदि उन चर में से एक सेट नहीं है, तो कोड एक चेतावनी देगा; आप नहीं देखेंगे कि चेतावनी समझ में आती है या नहीं (हो सकता है कि चर वैकल्पिक हो)।

एक बहुत ही सरल दृष्टिकोण एक फ़ंक्शन लिखना है, अधिमानतः एक बहुत ही संक्षिप्त नाम के साथ, जो इन दोनों का ख्याल रखता है; इसे कॉल करना _()एक सामान्य सम्मेलन लगता है। एक साधारण संस्करण इस तरह दिख सकता है:

function _($raw) {
    if (isset($raw)) {
        return htmlspecialchars($raw);
    }
}

और फिर अपने टेम्पलेट में, आप करेंगे:

<title><?= _($title) ?></title>

_()समारोह के साथ करने के लिए और चीजें :

  • htmlspecialcharsकॉल को ओवरराइड करने की अनुमति देने के लिए इसे एक दूसरा तर्क दें , उन मामलों के लिए जहां आप कच्चे तार के बजाय इसे HTML में पास करना चाहते हैं।
  • टाइप जाँच जोड़ें ताकि सरणियाँ और ऑब्जेक्ट उपज न हों Arrayऔर Object, बल्कि कुछ सार्थक (या रिक्त स्ट्रिंग)।
  • अंतर्राष्ट्रीयकरण समर्थन (अभी तक एक और तर्क) जोड़ें।
  • डिबग मोड में होने पर, कुछ विशेष स्वरूपण के साथ चर का नाम प्रिंट करें यदि यह परिभाषित नहीं है। इस तरह, आप एक झलक देख सकते हैं कि क्या टेम्प्लेट में कुछ गड़बड़ है।

1

पहला template.phpलोड करना आसान है जैसा कि ड्रीमविवर / ब्लूग्रिफ़ॉन में है / जो भी है और सर्वर-साइड गैर-प्रेमी वेब डिजाइनर द्वारा संपादित किया गया है, दूसरा ... अच्छी तरह से यह अभी भी थोड़े कर सकता है, लेकिन संपादन प्रक्रिया के दौरान इसके टूटने की संभावना अधिक है ।

मैं पहले वाले के साथ जाना चाहूंगा कि वह लाभ के साथ HTML जैसा दिखे , जिस तरह से 3 पार्टी डिजाइनर आमतौर पर पसंद करते हैं।


किस तरीके से? क्या आपका मतलब है कि इसे ड्रैग और ड्रॉप के इस्तेमाल से बदला नहीं जा सकता है? मूल रूप से दूसरा वाला पहले जैसा ही है, लेकिन PHP की एक दो पंक्तियों के साथ लिपटा हुआ है। तो यह मानते हुए कि यह हमेशा उस संरचना के पास है, उनके लिए हाथ से संपादित करना कोई कठिन नहीं है।
रयान

1
एक अच्छा टेम्पलेट डेवलपर्स के लिए समझ में आता है, एक महान टेम्पलेट डिजाइनरों के लिए समझ में आता है।
Citricguy

-3

Php एक प्रोग्रामिंग लैंग्वेज नहीं है। यदि आपकी भाषा में वास्तविक प्रकार की प्रणाली नहीं है, तो दृढ़ता से टाइप करना संभव नहीं है। लेकिन आप अपनी आईडीई की मदद पीएचपी-स्टॉर्म की तरह कर सकते हैं, जो आप चाहते हैं ...

आपके विचार की परिभाषा:

interface mySimpleView { 
  public function getTitle(); 
} 

आपकी टेम्प्लेट फ़ाइल:

<?php
/**
* @var $this mySimpleView  <== Your IDE will try to use this type.
*/
?>

<h1><?= $this->getTitle() ?></h1>
<p><?= $this->getContent() ?></p> <!-- <= IDE will warn you !  -->
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.