Help - Search - Members - Calendar
Full Version: Workaround for virtual() with PHP in CGI mode?
Hostony Board > General Support > PHP/MySQL
dvd3141
At some point recently, Hostony changed their PHP installation to run in CGI mode rather than as an Apache module. This affected code in my documents such as:

CODE
<?php virtual('/scgi-bin/foo.cgi') ?>


which I was using to include within my PHP documents the results of certain CGI scripts.

Does anyone know of a workaround so that I can reproduce the effect of virtual() when PHP is running in CGI mode?

David
Alexandre
Hello,

You can try to modify your scripts in this way:

QUOTE
#!/usr/bin/php
<?
php virtual('/scgi-bin/foo.cgi')
?>


wink.gif
dvd3141
Hi Alexandre,

If I understand what you're saying correctly, I put the #!/usr/bin/php at the top of my PHP file script.php?

I tried this but got the error message:

Fatal error: Call to undefined function: virtual() in /path/to/script.php on line 13

(I get the same error message without the #!/usr/bin/php.)

sad.gif
smokie
See this post, I had same trouble back in May

http://forum.hostony.com/index.php?showtopic=3996&hl=

Now Using
=======

<?php include("http://www.xxxxxx.com/cgi-bin/xxxxx/xxxxx.cgi"); ?>

Works for me biggrin.gif

I have no knowledge of php, just tried everything, and this worked for me

Smokie
dvd3141
QUOTE(smokie @ Dec 13 2005, 08:51 AM)
See this post, I had same trouble back in May

http://forum.hostony.com/index.php?showtopic=3996&hl=

Now Using
=======

<?php include("http://www.xxxxxx.com/cgi-bin/xxxxx/xxxxx.cgi"); ?>

Works for me biggrin.gif

I have no knowledge of php, just tried everything, and this worked for me

Smokie
*


Hi Smokie,

Thanks, I had already seen your previous post, and it works for some of my pages. smile.gif The trouble is, include() does not pass variables from a form onto the CGI script, so certain pages of mine (such as a site-search form) can't use this method. (The same goes for the require() function.) sad.gif
smokie
Well I tried smile.gif sorry it has'nt helped
MartinB
CODE
<?php
virtual('/full/path/to/scgi-bin/foo.cgi')
?>


is valid for a served page, and

CODE
#!/usr/bin/php -q
virtual('/full/path/to/scgi-bin/foo.cgi')


for a command-line script. Don't mix them up. :-)

The function is completely deprecated, anyway. What kind of CGI is it that can't be quickly re-written in PHP? As a last resort...

CODE
<?php
putenv('REQUEST_METHOD=POST');
putenv('QUERY_STRING=stringstringstring');
passthru('/full/path/to/scgi-bin/foo.cgi');
?>


Maybe that'll getcha where ya wanna go smile.gif
dvd3141
Thanks mblendinger, I tried this:

CODE
<?php

putenv('REQUEST_METHOD=GET');

$q = $_SERVER['QUERY_STRING'];

putenv('QUERY_STRING=$q');

passthru('/full/path/to/scgi-bin/foo.cgi');

?>


but I get no output whatsoever. unsure.gif Even if I comment out the query string stuff, I still get nothing. (The path to the CGI script is correct.)

It's Movable Type's mt-search.cgi script I'm trying to use, if that's of any use to you. I don't know enough about CGI or PHP to rewrite it in PHP (as you may have gathered!). wink.gif

David
MartinB
and:

CODE
<?php
// Change $file to the full url to your MT cgi search script
$file="http://www.yourdomain.com/cgi-bin/mt/mt-search.cgi";
readfile("$file?$_SERVER[QUERY_STRING]");
?>


?

I think you need to configure the php setting "allow_url_fopen" to On if you need to use readfile(), you can change it from your php.ini file, if it's off.
MartinB
That can be useful for you: PHP, CGI, and MT: Together at Last

It's for MTComments, but maybe you can extract your solution:

PHP, CGI, and MT: Together at Last
July 08, 2004 4PM PST

A long-standing problem with Movable Type’s templating system is that the Perl-based .cgi files it relies on don’t allow for the use of PHP. That’s changing though.

The lovely and talented Shaun Inman wrote up his method of using PHP includes to pull in CGI data back in January, which allowed him to pass a query string to the script using HTTP GET. Technical details are at Shaun’s, go read and come back when you’re done.

Using his thinking as a starting point, I spent some time a few weeks back tweaking to solve another Movable Type problem — the comment preview pages that are so often the neglected children of sites like, say, this one.

The problem is that I use PHP to include a standard set of header and footer files across the site; changing one of those files changes the entire site equally. Includes are a beautiful thing, but .cgi files won’t allow you to run PHP. So the only solution I’ve had till now is to flatten a copy of my HTML, reduce it to the bare minimum, and drop the whole thing into my preview template. Which results in parts of the site falling further and further out of synch with the rest as things change.

Out of the box, Movable Type jumps all comment previews and new comment posts to a file called mt-comment.cgi after you hit the submit button, which does the parsing and filtering and spits out a result based on whichever template you have told Movable Type to use. (There are a few possible templates here including those for Comment Preview, Comment Listing, Comment Error, and new in MT3, Comment Pending. Defining a non-default template for each of these is important and I haven’t yet spent the time figuring out how to apply this to Error or Pending.)

Comment Preview is the one we’re trying to hook into. Instead of relying on the .cgi file to render the whole page, instead what I’ve done is strip the template to a bare minimum, and hijack the Individual Entry Archive to point to a different PHP file that includes it.

So that’s the summary, but it’s difficult to make sense of that without the examples. First step, having the Individual Entry Archive and Comment Preview pages point to the new PHP file instead of mt-comments.cgi. Look for the line that goes like this:

CODE
<form method="post"
action="<$MTCGIPath$><$MTCommentScript$>"
name="comments_form">


And change it to this (replacing the /path/to/preview.php with the path to the .php file on your own server, of course):

CODE
<form method="post"
action="/path/to/preview.php"
name="comments_form">


Do that with both templates. Next step is to build the actual PHP file that does the heavy lifting. Since your site will require custom includes and a completely different wrapper than my own, there’s no point in listing the whole file. Instead, here’s the code you’ll need. Drop this first bit in the page header, before anything else happens. (Thanks to Dan Benjamin for help with the Post to Get conversion. All insanely genius type code is his; all mucking-around-without-a-clue type code is mine.)

CODE
<?php

function makeGetRequest( $str ) {
$result = str_replace(':','%3A',$str);
$result = str_replace('/','%2F',$result);
$result = str_replace('@','%40',$result);
return $result;
}

if ($_POST['post']) {
$variables = 'entry_id=' . $_POST['entry_id'] . '&static=' . $_POST['static'];
$variables .= '&author=' . urlencode($_POST['author']) . '&email=' . $_POST['email'];
$variables .= '&url=' . $_POST['url'] . '&text=' . urlencode(stripslashes($_POST['text']));
$variables .= '&post=post' . '&bakecookie=' . $_POST['bakecookie'];
    
makeGetRequest($variables);
readfile("http://www.example.com/path/to/mt-comments.cgi?$variables");

exit;
}




Drop this second bit later in the page, where you’d normally place the preview text and the comment form.

CODE
<?php

if ($_POST) {
$variables = 'entry_id=' . $_POST['entry_id'] . '&static=' . $_POST['static'];
$variables .= '&author=' . urlencode($_POST['author']) . '&email=' . $_POST['email'];
$variables .= '&url=' . $_POST['url'] . '&text=' . urlencode(stripslashes($_POST['text']));
$variables .= '&preview=Preview+Comment' . '&bakecookie=' . $_POST['bakecookie'];
    
makeGetRequest($variables);
readfile("http://www.example.com/path/to/mt-comments.cgi?$variables");
} else {
echo "
 <p>This is the comment preview form. You’re seeing this message because either something went wrong, or you’ve typed in the URL, or you clicked a link that shouldn’t have been pointing here in the first place.</p>
 <p>Whatever the case, there should be a form here, but there isn’t because of the above reasons. So if you were expecting a comment preview form, <a href=\"/contact/\">let me know that you got this instead</a>. Otherwise, hit the back button and try again. Thanks!</p>
 <hr />
 <p>For the sake of debugging and possibly retrieving your comment, this is the data that was posted to this page:</p>
 "; echo $_POST;
}
?>


The message in the second half is just a bit of defensive design to let the user know there’s a problem if somehow they wind up on the preview page without going through the proper channel. Just in case something goes wrong, I’m dumping the post data as well to allow retrieval, though I can’t foresee much chance of it ever being displayed. Never hurts to be helpful though.

At this point, it should work — but the comment preview page will look a little off. You need to strip everything but the essentials if you’re going to be including the rest of your site structure. This will usually mean taking out everything from the HTML <html> start tag to where the comment preview form begins, and everything after to the </html>. For what it’s worth, my revised, light preview template:

CODE
<div class="reply">
<p class="postedBy"><$MTCommentPreviewAuthorLink show_email="0"$> says:</p>
<div class="reply-body">
 <$MTCommentPreviewBody$></p>

</div>
<p class="posttimestamp">Posted on <$MTCommentPreviewDate$> §</p>
</div>

<hr class="divider" />

<div class="comments-body">
<h2 class="dom">Edit / Post Your Comment:</h2>

<form method="post" action="/path/to/preview.php" name="comments_form" onsubmit="if (this.bakecookie.checked) rememberMe(this)">
<div id="replyForm">
<input type="hidden" id="entry_id" name="entry_id" value="<$MTEntryID$>" />
<input type="hidden" name="static" value="1" />

<span><label for="author">Name:</label><input type="text" id="author" name="author" value="<$MTCommentPreviewAuthor encode_html="1"$>" /></span>
<span><label for="email">Email Address:</label><input type="text" id="email" name="email" value="<$MTCommentPreviewEmail encode_html="1"$>" /></span>
<span><label for="url">URL:</label><input type="text" id="url" name="url" value="<$MTCommentPreviewURL encode_html="1"$>" /></span>
<span><label for="text">Comments:</label><textarea id="text" name="text" rows="13" cols="55"><$MTCommentPreviewBody convert_breaks="0" encode_html="1" $></textarea></span>
<span class="submit">
 <input type="submit" id="preview" name="preview" value="Preview Again" />
 <input type="submit" id="post" name="post" value="Post" />&nbsp;
</span>
</form>
</div>

<hr class="divider" />

<h2 class="dom">Previous Comments</h2>

<MTComments>
<div class="reply">
<span class="replynumber"><a href="#c<$MTCommentID pad="3"$>"><$MTCommentOrderNumber$></a></span>
<p class="postedBy"><$MTCommentAuthorLink show_email="0"$> says:</p>
<div class="reply-body">
 <MTMacroApply><$MTCommentBody regex="1" smarty_pants="2"$></MTMacroApply>
</div>
<p class="posttimestamp">Posted on <$MTCommentDate$> <a href="#c<$MTCommentID pad="3"$>">§</a></p>
</div>
</MTComments>

</div>


It’s not perfect. The conversion dropped out a few of the custom filters I relied on to get rid of things like SmartyPants-generated “smart quotes”, and things are messy when Unicode characters are pasted. But it’s been running for almost a month now and I haven’t received any nasty emails about comment loss, so the basic functionality is there.

As always, share and enjoy.


Good luck with it, I think now you have a little work to do wink.gif
MartinB
Another case:

QUOTE

I set it up to:

  1. use a search page located at /search/index.php
  2. place IncludeBlogs= in one location outside of <form>.

The method:

  1.

      The form code:

      <form method="get" action="http://your_url.com/search/index.php">
          <input value="Site Search" name="search" id="search" >
          <input type="submit" value="Search" />
      </form>

  2.

      The code to use in /search/index.php to show output of mt-search.cgi

      <?php
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL,
      "http://your_url.com/path_to/mt-search.cgi");
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS,
                  "IncludeBlogs= blog id # you want to search&IncludeBlogs=blog
      id # you want to search&$_SERVER[QUERY_STRING]");


      curl_exec($ch);
      curl_close($ch);
      ?>

  3.

      For /path_to_your_mt/search_templates/default.tmpl strip and use desired <MTSearchResults> tags and form tags.
dvd3141
Thanks very much for all your research efforts! The first one you suggested worked a treat:

QUOTE(mblendinger @ Dec 15 2005, 03:41 PM)
CODE
<?php
// Change $file to the full url to your MT cgi search script
$file="http://www.yourdomain.com/cgi-bin/mt/mt-search.cgi";
readfile("$file?$_SERVER[QUERY_STRING]");
?>


I think you need to configure the php setting "allow_url_fopen" to On if you need to use readfile(), you can change it from your php.ini file, if it's off.
*


biggrin.gif
MartinB
Your welcome, glad to help you ! Merry christmas ho ho hooooooooo blink.gif
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2024 Invision Power Services, Inc.
IPS Driver Error

IPS Driver Error

There appears to be an error with the database.
You can try to refresh the page by clicking here