LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Can't run PHP script on Linux virtual server (https://www.linuxquestions.org/questions/linux-newbie-8/cant-run-php-script-on-linux-virtual-server-885053/)

shanekelly 06-07-2011 03:04 PM

Can't run PHP script on Linux virtual server
 
Hi There,

I'm having problems running an email form written in PHP on my virtual unix server.

I know the script works on my other sites outside the virtual server. I've checked the permissions read, write & execute Do I need to change the mailserver settings to allow it to send email?

Also, when configuring the server should I have PHP run as CGI in safe mode? Please forgive any glaring mistakes. It's all new to me. Many thanks.

kbp 06-07-2011 10:19 PM

Does php work at all ? .. try creating a file with:

Code:

<?php
phpinfo();
?>


frieza 06-07-2011 10:49 PM

first of all, you DO NOT need write OR execute permissions for php scripts, that is a potential security hole, php is an interpreted language, parsed an executed by an interpreter and doesn't need execute permission, and adding write permissions to the web server could allow code to be injected into your scripts, you only need READ permissons

second of all, what happens when you try to browse to the php script, does it show an error? display the contents in the browser? offer a dialog box to download the file?

web server files should be chmod 644 (-rw-r--r--), directories 755 (drwxr-xr-x)
the owner should be your user account, not the web server's account so only you can edit the files, not the web server

shanekelly 06-08-2011 09:28 AM

Thanks Frieza,

I'll change the file permissons back as you said!

When my form posts the data to the php file. I get an error produced by php itself that says it's not received an email from field. The php looks for @ characters to validate the info being sent. This same scriptworks perfectly on other websites though?

If I'm running php for this does it have to be stored in my httpdocs folder? Or do I have to store it somewhere else? The only other thing I thought of, is that the php sends the info as an email?

Many thanks for your help.

- shanekelly

Wim Sturkenboom 06-08-2011 10:49 AM

Time to show your code ;)

Anything in the webserver's log files (/var/log/httpd or/var/log/apache) ?

blue_print 06-08-2011 10:03 PM

Please try testing your mail function as shown in http://email.about.com/od/emailprogr...PHP_Script.htm

Let us know if this works for u. if any errors, please paste here.

shanekelly 06-09-2011 05:02 AM

I am getting error logs that mention

invalid arguments for each ()

on lines 127, 139, 143, 238, 258, 285

I've highlighted the errors in red

This is the PHP!
<?
/**
* aFormMail script - sending mail via form

*/

/*****************************************************************************
* *
* C O N F I G U R A T I O N *
* *
*****************************************************************************/

// email for send submitted forms //////////////////////////////////////////thedomainname////////////////////////////
// if empty, use value from form ('send_to' field)
$send_to = "thecompanyname Sales Enquiry <info@thedomainname.co.uk>";

// set $send_cc address if you need copy of mail to other addresses
// for example: $send_cc = array('friend1@ccc.cc', 'friend2@ccc.cc');
//
$send_cc = array('webmaster@thedomainname.co.uk');

// Subject. if empty, use value from form ('subject' field)
$subject = "thecompanyname Enquiry";

// Allowed Referres. Should be empty or list of domains
$referrers = array();

// Attachments
$attachment_enabled = 0;

////// Database - write CSV file with data of submitted forms //////////////
//$database_enabled = 1;
//$database_file = 'email.csv';

// Fields to collect
// $database_fields = '*' - mean all fields, as in form
// $database_fields = array('from', 'subject') - only 'from', 'subject' fields
$database_fields = '*';

////// Redirect user after submitting form
$redirect_url = '/php/thankyou.html';

////// Auto-Responder
////// You can substitute any of form fields in response by using
////// %field_name% in response text.
//////
$autoresponder_enabled = 1;
$autoresponder_from = $send_to;
$autoresponder_subject = "%subject% (autoresponse)";
$autoresponder_message = <<<MSG
Dear %name_from%,

Thank you for your enquiry regarding thecompanyname products. We will strive to reply to you as soon as we can.

Kind regards
The thecompanyname Team

thecompanyname

Your original message
%textarea%

--
MSG;

/***************************************************************************/

function do_formmail(){
global $autoresponder_enabled, $database_enabled;
$form = get_form_data();
$errors = check_form($form);
if ($errors) {
display_errors($errors);
return;
}
send_mail($form);
if ($autoresponder_enabled)
auto_respond($form);
if ($database_enabled)
save_form($form);
redirect();
}

function redirect(){
global $redirect_url;
header("Location: $redirect_url");
exit();
}

/*
function save_form($vars){
global $database_file, $database_fields;
$f = fopen($database_file, 'a');
if (!$f){
die("Cannot open db file for save");
}
foreach ($vars as $k=>$v) {
$vars[$k] = str_replace(array("|", "\r","\n"), array('_',' ',' '), $v);
}
if (is_array($database_fields)) {
$vars_orig = $vars;
$vars = array();
foreach ($database_fields as $k)
$vars[$k] = $vars_orig[$k];
}
$str = join('|', $vars);
fwrite($f, $str."\n");
fclose($f);
}
*/
function auto_respond($vars){
global $autoresponder_from, $autoresponder_message, $autoresponder_subject;
/// replace all vars in message
$msg = $autoresponder_message;
preg_match_all('/%(.+?)%/', $msg, $out);
$s_vars = $out[1]; //field list to substitute
foreach ($s_vars as $k)
$msg = str_replace("%$k%", $vars[$k], $msg);
/// replace all vars in subject
$subj = $autoresponder_subject;
preg_match_all('/%(.+?)%/', $subj, $out);
$s_vars = $out[1]; //field list to substitute
foreach ($s_vars as $k)
$subj = str_replace("%$k%", $vars[$k], $subj);
//
$_send_to = "$vars[name_from] <".$vars[email_from].">";
$_send_from = $autoresponder_from;
mail($_send_to, $subj, $msg, "From: $_send_from");
}

function _build_fields($vars){
$skip_fields = array(
'email_to',
'name_to',
'subject');
// order by numeric begin, if it exists
$is_ordered = 0;
foreach ($vars as $k=>$v)
if (in_array($k, $skip_fields)) unset($vars[$k]);

$new_vars = array();
foreach ($vars as $k=>$v){
// remove _num, _reqnum, _req from end of field names
$k = preg_replace('/_(req|num|reqnum)$/', '', $k);
// check if the fields is ordered
if (preg_match('/^\d+[ \:_-]/', $k)) $is_ordered++;
//remove number from begin of fields
$k = preg_replace('/^\d+[ \:_-]/', '', $k);
$new_vars[$k] = $v;
}
$vars = $new_vars;

$max_length = 10; // max length of key field
foreach ($vars as $k=>$v) {
$klen = strlen($k);
if (($klen > $max_length) && ($klen < 40))
$max_length = $klen;
}

if ($is_ordered)
ksort($vars);

// make output text
$out = "";
foreach ($vars as $k=>$v){
$k = str_replace('_', ' ', $k);
$k = ucfirst($k);
$len_diff = $max_length - strlen($k);
if ($len_diff > 0)
$fill = str_repeat('.', $len_diff);
else
$fill = '';
$out .= $k."$fill...: $v\n";
}
return $out;
}


function send_mail($vars){
global $send_to, $send_cc;
global $subject;
global $attachment_enabled;
global $REMOTE_ADDR;

global $HTTP_POST_FILES;
$files = array(); //files (field names) to attach in mail
if (count($HTTP_POST_FILES) && $attachment_enabled){
$files = array_keys($HTTP_POST_FILES);
}

// build mail
$date_time = date('Y-m-d H:i:s');
$mime_delimiter = md5(time());
$fields = _build_fields($vars);
$mail = <<<EOF
This is a MIME-encapsulated message

--$mime_delimiter
Content-type: text/plain
Content-Transfer-Encoding: 8bit

Email sent from thecompanyname web site's contact form:
$fields
--------------------
REMOTE IP : $REMOTE_ADDR
DATE/TIME : $date_time
EOF;

if (count($files)){
foreach ($files as $file){
$file_name = $HTTP_POST_FILES[$file]['name'];
$file_type = $HTTP_POST_FILES[$file]['type'];
$file_tmp_name = $HTTP_POST_FILES[$file]['tmp_name'];
$file_cnt = "";
$f=@fopen($file_tmp_name, "rb");
if (!$f)
continue;
while($f && !feof($f))
$file_cnt .= fread($f, 4096);
fclose($f);
if (!strlen($file_type)) $file_type="applicaton/octet-stream";
if ($file_type == 'application/x-msdownload')
$file_type = "applicaton/octet-stream";

$mail .= "\n--$mime_delimiter\n";
$mail .= "Content-type: $file_type\n";
$mail .= "Content-Disposition: attachment; filename=\"$file_name\"\n";
$mail .= "Content-Transfer-Encoding: base64\n\n";
$mail .= chunk_split(base64_encode($file_cnt));
}
}
$mail .= "\n--$mime_delimiter--";


//send to
$_send_to = $send_to ? $send_to : "$vars[name_to] <".$vars[email_to].">";
$_send_from = "$vars[name_from] <".$vars[email_from].">";
$_subject = $subject ? $subject : $vars['subject'];

mail($_send_to, $_subject, $mail,
"Mime-Version: 1.0\r\nFrom: $_send_from\r\nContent-Type: multipart/mixed;\n boundary=\"$mime_delimiter\"\r\nContent-Disposition: inline");

foreach ($send_cc as $v){
mail($v, $_subject, $mail,
"Mime-Version: 1.0\r\nFrom: $_send_from\r\nContent-Type: multipart/mixed;\n boundary=\"$mime_delimiter\"\r\nContent-Disposition: inline");
}

}

function get_form_data(){
global $REQUEST_METHOD;
global $HTTP_POST_VARS;
global $HTTP_GET_VARS;

$vars = ($REQUEST_METHOD == 'GET') ? $HTTP_GET_VARS : $HTTP_POST_VARS;
//strip spaces from all fields
foreach ($vars as $k=>$v) $vars[$k] = trim($v);
return $vars;
}

function check_form($vars){
global $referrers;
global $send_to;
global $subject;
global $HTTP_REFERER;

$errors = array();

// check from email set
if (!strlen($vars['email_from'])){
$errors[] = "<b>The From Email address</b> is empty";
} else if (!check_email($vars['email_from'])){
$errors[] = "<b>The From Email address</b> is incorrect";
}
if (!strlen($send_to) && !strlen($vars['email_to'])){
$errors[] = "<b>To Email</b> address empty (possible configuration error)";
} else if (!strlen($send_to) && !check_email($vars['email_to'])){
//if to email specified in form, check it and display error
$errors[] = "<b>To Email address</b> incorrect";
}
if (!strlen($vars['subject']) && !strlen($subject)){
$errors[] = "<b>Subject</b> empty (possible configuration error)";
}
foreach ($vars as $k=>$v){
// check for required fields (end with _req)
if (preg_match('/^(.+?)_req$/i', $k, $m) && !strlen($v)){
$field_name = ucfirst($m[1]);
$errors[] = "Required field <b>$field_name</b> empty";
}
// check for number fields (end with _num)
if (preg_match('/^(.+?)_num$/i', $k, $m) && strlen($v) && !is_numeric($v)){
$field_name = ucfirst($m[1]);
$errors[] = "Field <b>$field_name</b> must contain only digits or be empty";
}
// check for number & required fields (end with _reqnum)
if (preg_match('/^(.+?)_reqnum$/i', $k, $m) && !is_numeric($v)){
$field_name = ucfirst($m[1]);
$errors[] = "Field <b>$field_name</b> must contain digits and only digits";
}
}

//check referrer
if (is_array($referrers) && count($referrers)){
$ref = parse_url($HTTP_REFERER);
$host = $ref['host'];
$host_found = 0;
foreach ($referrers as $r){
if (strstr($host, $r))
$host_found++;
}
if (!$host_found){
$errors[] = "Unknown Referrer: <b>$host</b>";
}
}
return $errors;
}

function display_errors($errors){
$errors = '<li>' . join('<li>', $errors);
print <<<EOF
<html>
<head><title>An error has occured</title></head>
<body bgcolor=white>
<div align="center"><a href="/index.htm" target="_self"><img src="/images/logo.jpg" alt="Go to the thecompanyname home page?" width="400" height="142" border="0" align="top"></a><br><br>
<h3 align=center><font color=red>WARNING!</font></h3><br><br>
<h3 align=center><font color=red>An Error Has Occured</font></h3>
<hr width=80%>
<table align=center><tr><td>
$errors
</td></tr></table>
<p align=center>
<a href="javascript: history.back(-1)">Return</a> and fix these errors
</p>
<hr width=80%>
<center>
<font size=2><a href="/index.html">thecompanyname Home Page</a>, 2011&copy</font>
</center>
</body></html>
EOF;
}


/**
* Check email using regexes
* @param string email
* @return bool true if email valid, false if not
*/
function check_email($email) {
#characters allowed on name: 0-9a-Z-._ on host: 0-9a-Z-. on between: @
if (!preg_match('/^[0-9a-zA-Z\.\-\_]+\@[0-9a-zA-Z\.\-]+$/', $email))
return false;

#must start or end with alpha or num
if ( preg_match('/^[^0-9a-zA-Z]|[^0-9a-zA-Z]$/', $email))
return false;

#name must end with alpha or num
if (!preg_match('/([0-9a-zA-Z_]{1})\@./',$email) )
return false;

#host must start with alpha or num
if (!preg_match('/.\@([0-9a-zA-Z_]{1})/',$email) )
return false;

#pair .- or -. or -- or .. not allowed
if ( preg_match('/.\.\-.|.\-\..|.\.\..|.\-\-./',$email) )
return false;

#pair ._ or -_ or _. or _- or __ not allowed
if ( preg_match('/.\.\_.|.\-\_.|.\_\..|.\_\-.|.\_\_./',$email) )
return false;

#host must end with '.' plus 2-5 alpha for TopLevelDomain
if (!preg_match('/\.([a-zA-Z]{2,5})$/',$email) )
return false;

return true;
}

do_formmail();
?>


Many thanks for this

-Shane

blue_print 06-09-2011 08:44 PM

It seems like some PHP code ues with the script. You may want to check this with any PHP developer.

frieza 06-09-2011 11:41 PM

looks like the offending variable is $vars

i would do a var_dump($vars);
at the lines preceding the lines that are causing the error to make sure it even contains data, and if it does, that it is an array.

shanekelly 06-10-2011 09:36 AM

Thanks everyone for your help. I tested a far simpler mailer and that worked. So in the end I started using a different script. It's working now.

Because the virtual server environment is unfamiliar to me. I was unsure what could be going wrong and where. I'm enjoying getting my head around it all though. Thanks again.


All times are GMT -5. The time now is 06:16 PM.