views:

50

answers:

3

Hi,

Is it possible to bypass any controller in a Zend Framework web site? Instead I want a normal PHP script executed and all its output should be placed in the layout/view coming from ZF:

Request --> Execute PHP script --> Catch output --> Add output to view --> Send response

The challenge is to integrate existing pages/scripts into a newly created Zend Framework site which is working with the MVC pattern.

Cheers

A: 

Make a standard php include/require in your view to embed the output of your php scripts

gustavogb
This won't work unless you call it from the View, other wise it will just be placed after the actual View contents. Also, depending on how the output is formatted, there may be some extra tags to parse out (HTML, HEAD, BODY, etc...). It would probably be better to handle that in the Controller and/or Model, but not the View.
pferate
+1  A: 

In your Controller (or Model) you can add:

$output = shell_exec('php /local/path/to/file.php');

At that point you can parse and clean up $output as needed and then store it in your View.

You can store the php file you are going to execute in your scripts directory.

If the PHP file is stored on a remote server you can use:

$output = file_get_contents('http://www.example.com/path/to/file.php');
pferate
I don't think `shell_exec()` fills the `$_SERVER` variables which might cause the php script not to run.
chelmertz
+5  A: 

I created a new entry in my .htaccess file:

RewriteRule (.*).php(.*)$ index.php [NC,L]

Every request on a usual .php file is handled by index.php from ZF now.

Next I created an additional route to route those requests to a certain controller action:

$router->addRoute(
  'legacy',
  new Zend_Controller_Router_Route_Regex(
    '(.+)\.php$',
    array(
      'module' => 'default',
      'controller' => 'legacy',
      'action' => 'index'
    )
  )
);

And this is the appropriate action:

public function indexAction() {
  $this->_helper->viewRenderer->setNoRender();
  $this->_helper->layout->setLayout('full');

  // Execute the script and catch its output
  ob_start();
  require($this->_request->get('DOCUMENT_ROOT') . $this->_request->getPathInfo());
  $output = ob_get_contents();
  ob_end_clean();

  $doc = new DOMDocument();
  // Load HTML document and suppress parser warnings
  @$doc->loadHTML($output);

  // Add keywords and description of the page to the view
  $meta_elements = $doc->getElementsByTagName('meta');
  foreach($meta_elements as $element) {
    $name = $element->getAttribute('name');
    if($name == 'keywords') {
      $this->view->headMeta()->appendName('keywords', $element->getAttribute('content'));
    }
    elseif($name == 'description') {
      $this->view->headMeta()->appendName('description', $element->getAttribute('content'));
    }
  }

  // Set page title
  $title_elements = $doc->getElementsByTagName('title');
  foreach($title_elements as $element) {
    $this->view->headTitle($element->textContent);
  }

  // Extract the content area of the old page
  $element = $doc->getElementById('content');
  // Render XML as string
  $body = $doc->saveXML($element);

  $response = $this->getResponse();
  $response->setBody($body);
}

Very useful: http://www.chrisabernethy.com/zend-framework-legacy-scripts/

+1 for the reference to the Chris Abernethy page which is awesome.
David Weinraub
@user413773: How do you handle a request to **site.com/news/** which is supposed to be **site.com/news/index.php** and not `NewsController::indexAction()`
chelmertz