0

I've been learning php and following the examples on w3schools until I came to this example and now I'm pretty stuck after having tried to make it work for countless hours.

This is the bit I'm on: http://www.w3schools.com/php/php_mail.asp

I try to send the email using the following code:

<?php
$to = "someone@example.com"; //I changed this with my email address
$subject = "Test mail";
$message = "Hello! This is a simple email message.";
$from = "someonelse@example.com";
$headers = "From:" . $from;
mail($to,$subject,$message,$headers);
echo "Mail Sent.";
?>

When I open the page I get the following error message:
Warning: mail() [function.mail]: Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set()

I've tried to find out about it on google apparently the php.ini file needs to be changed to accomodate this but some of the instructions were written in a very complicated way and I was unable to follow so if it can be explained in simple terms - it would be greatly appreciated!

4
Contributors
9
Replies
10
Views
6 Years
Discussion Span
Last Post by asif49
0

Are you running from your personal machine or a webserver ? If you are running from your local machine, then it is hard to get it to work, because you either need an smtp server on your machine, or you need to connect to a mail provider which doesn't need authentication (most do).

0

I've set up a home server (as far as I know it's called that). I'm using xampp and use "localhost/" to access the page on google chrome.

Are you saying that if this was hosted on the web then this problem would dissapear?

0

I've set up a home server (as far as I know it's called that). I'm using xampp and use "localhost/" to access the page on google chrome.

Are you saying that if this was hosted on the web then this problem would dissapear?

Most likely. Every time I've encountered this problem, it is resolved as soon as it is hosted on a server with a SMTP.

0

Most likely. Every time I've encountered this problem, it is resolved as soon as it is hosted on a server with a SMTP.

Ahh. If that's the case I have nothing to worry about. By the way, did you have to change anything in php.ini etc.

0

Not usually on a properly-configured server with SMTP.

In the past, I have found that it sometimes works on a local machine if you configure the SMTP line in php.ini to point to the SMTP server of your ISP.

Sometimes it works, sometimes it doesn't- depends on your ISP and what kinds of restrictions they have on their SMTP server (usually whether they require SMTP authentication).

So if you have, say, Comcast as your ISP and their SMTP server address is "smtp.comcast.net" on port 25, you could try changing your php.ini file so that it reads like this:

SMTP = smtp.comcast.net
smtp_port = 25

Feel free to try that out, but don't be surprised if you don't have any luck. Also, I should note that the above php.ini configuration is for Windows. Unix servers rely on the "sendmail_path" line for that configuration. But that's only if you have sendmail set up on your server.

Oh, and if you do try that out, remember to save a backup of php.ini first. You probably know that already, but I feel obligated to say it, knowing the hell I've put myself through by messing with php.ini without a backup.

Edited by TySkby: n/a

0

Hmm I've just tried changing the SMTP line from "localhost" to my ISP and still no luck. Do you think I should just leave it now with smtp being my ISP or change it back to "localhost" as it was. Because I doubt I'll be hosting this website and testing it on the web anytime soon.

What would you reccomend based on which one of these options will have more of a chance of making the mail function work (if any?)

0

Don't worry I managed to find a free web hosting place, uploaded the page, and it works :D:D

0

Hi folks,

Sorry for the late reply but I thought it worth mentioning that you can use PEAR to send emails from your local server if you have a gmail or yahoo email account.

PEAR is included in most XAMPP type installations so you can just replace the 'Mail' sub-folder inside the PEAR directory with the folder I have attached (to make sure you have the correct, up-to-date files).

Add the attached 'mail.php' to your include directory (or the PEAR directory) and include the following code to actually send the email (remember to change the 7 commented parameters at the top of the code).

<?php
require_once "mail.php";


$to = "Somebody <somebody@somewhere.com>"; // This is who you want to sent the message to.
$subject = "From localhost via PEAR"; // This is the email subject.
$body = "Hi,\n\nHow are you doing?"; // This is the email message.

$name = "Your Name"; // This should be your name.
$provider = "gmail"; // Should be 'gmail' or 'yahoo'.
$username = "you@gmail.com"; // This is your Gmail/Yahoo email address.
$password = "password"; // This is your Gmail/Yahoo password.


if ($provider == "gmail"){
	$host = "ssl://smtp.googlemail.com";
}
elseif ($provider == "yahoo"){
	$host = "ssl://smtp.mail.yahoo.com";
}
else{
	exit ("This script is currently only set up to work with yahoo or gmail accounts.");
}
$port = "465";
$from = $name . " <" . $username . ">";
$headers = array ('From' => $from,
'To' => $to,
'Subject' => $subject);
$smtp = Mail::factory('smtp',
array ('host' => $host,
'port' => $port,
'auth' => true,
'username' => $username,
'password' => $password));

// The lines below are the actual command to send the email so all the code above could be an 'included' file to reduce space. 
$mail = $smtp->send($to, $headers, $body);
if (PEAR::isError($mail)) {
echo("<p>" . $mail->getMessage() . "</p>");
} else {
echo("<p>Message successfully sent!</p>");
}
?>

This does generate a bunch of errors if you have error reporting set to E_STRICT but is fine if set to E_ALL. The email gets sent either way.

Hope this helps.


Zagga

Attachments
<?php
/**
 *  PEAR's Mail:: interface.
 *
 * PHP versions 4 and 5
 *
 * LICENSE:
 *
 * Copyright (c) 2002-2007, Richard Heyes
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * o Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * o Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * o The names of the authors may not be used to endorse or promote
 *   products derived from this software without specific prior written
 *   permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @category    Mail
 * @package     Mail
 * @author      Chuck Hagenbuch <chuck@horde.org>
 * @copyright   1997-2010 Chuck Hagenbuch
 * @license     http://opensource.org/licenses/bsd-license.php New BSD License
 * @version     CVS: $Id: Mail.php 294747 2010-02-08 08:18:33Z clockwerx $
 * @link        http://pear.php.net/package/Mail/
 */

require_once 'PEAR.php';

/**
 * PEAR's Mail:: interface. Defines the interface for implementing
 * mailers under the PEAR hierarchy, and provides supporting functions
 * useful in multiple mailer backends.
 *
 * @access public
 * @version $Revision: 294747 $
 * @package Mail
 */
class Mail
{
    /**
     * Line terminator used for separating header lines.
     * @var string
     */
    var $sep = "\r\n";

    /**
     * Provides an interface for generating Mail:: objects of various
     * types
     *
     * @param string $driver The kind of Mail:: object to instantiate.
     * @param array  $params The parameters to pass to the Mail:: object.
     * @return object Mail a instance of the driver class or if fails a PEAR Error
     * @access public
     */
    function &factory($driver, $params = array())
    {
        $driver = strtolower($driver);
        @include_once 'Mail/' . $driver . '.php';
        $class = 'Mail_' . $driver;
        if (class_exists($class)) {
            $mailer = new $class($params);
            return $mailer;
        } else {
            return PEAR::raiseError('Unable to find class for driver ' . $driver);
        }
    }

    /**
     * Implements Mail::send() function using php's built-in mail()
     * command.
     *
     * @param mixed $recipients Either a comma-seperated list of recipients
     *              (RFC822 compliant), or an array of recipients,
     *              each RFC822 valid. This may contain recipients not
     *              specified in the headers, for Bcc:, resending
     *              messages, etc.
     *
     * @param array $headers The array of headers to send with the mail, in an
     *              associative array, where the array key is the
     *              header name (ie, 'Subject'), and the array value
     *              is the header value (ie, 'test'). The header
     *              produced from those values would be 'Subject:
     *              test'.
     *
     * @param string $body The full text of the message body, including any
     *               Mime parts, etc.
     *
     * @return mixed Returns true on success, or a PEAR_Error
     *               containing a descriptive error message on
     *               failure.
     *
     * @access public
     * @deprecated use Mail_mail::send instead
     */
    function send($recipients, $headers, $body)
    {
        if (!is_array($headers)) {
            return PEAR::raiseError('$headers must be an array');
        }

        $result = $this->_sanitizeHeaders($headers);
        if (is_a($result, 'PEAR_Error')) {
            return $result;
        }

        // if we're passed an array of recipients, implode it.
        if (is_array($recipients)) {
            $recipients = implode(', ', $recipients);
        }

        // get the Subject out of the headers array so that we can
        // pass it as a seperate argument to mail().
        $subject = '';
        if (isset($headers['Subject'])) {
            $subject = $headers['Subject'];
            unset($headers['Subject']);
        }

        // flatten the headers out.
        list(, $text_headers) = Mail::prepareHeaders($headers);

        return mail($recipients, $subject, $body, $text_headers);
    }

    /**
     * Sanitize an array of mail headers by removing any additional header
     * strings present in a legitimate header's value.  The goal of this
     * filter is to prevent mail injection attacks.
     *
     * @param array $headers The associative array of headers to sanitize.
     *
     * @access private
     */
    function _sanitizeHeaders(&$headers)
    {
        foreach ($headers as $key => $value) {
            $headers[$key] =
                preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
                             null, $value);
        }
    }

    /**
     * Take an array of mail headers and return a string containing
     * text usable in sending a message.
     *
     * @param array $headers The array of headers to prepare, in an associative
     *              array, where the array key is the header name (ie,
     *              'Subject'), and the array value is the header
     *              value (ie, 'test'). The header produced from those
     *              values would be 'Subject: test'.
     *
     * @return mixed Returns false if it encounters a bad address,
     *               otherwise returns an array containing two
     *               elements: Any From: address found in the headers,
     *               and the plain text version of the headers.
     * @access private
     */
    function prepareHeaders($headers)
    {
        $lines = array();
        $from = null;

        foreach ($headers as $key => $value) {
            if (strcasecmp($key, 'From') === 0) {
                include_once 'Mail/RFC822.php';
                $parser = new Mail_RFC822();
                $addresses = $parser->parseAddressList($value, 'localhost', false);
                if (is_a($addresses, 'PEAR_Error')) {
                    return $addresses;
                }

                $from = $addresses[0]->mailbox . '@' . $addresses[0]->host;

                // Reject envelope From: addresses with spaces.
                if (strstr($from, ' ')) {
                    return false;
                }

                $lines[] = $key . ': ' . $value;
            } elseif (strcasecmp($key, 'Received') === 0) {
                $received = array();
                if (is_array($value)) {
                    foreach ($value as $line) {
                        $received[] = $key . ': ' . $line;
                    }
                }
                else {
                    $received[] = $key . ': ' . $value;
                }
                // Put Received: headers at the top.  Spam detectors often
                // flag messages with Received: headers after the Subject:
                // as spam.
                $lines = array_merge($received, $lines);
            } else {
                // If $value is an array (i.e., a list of addresses), convert
                // it to a comma-delimited string of its elements (addresses).
                if (is_array($value)) {
                    $value = implode(', ', $value);
                }
                $lines[] = $key . ': ' . $value;
            }
        }

        return array($from, join($this->sep, $lines));
    }

    /**
     * Take a set of recipients and parse them, returning an array of
     * bare addresses (forward paths) that can be passed to sendmail
     * or an smtp server with the rcpt to: command.
     *
     * @param mixed Either a comma-seperated list of recipients
     *              (RFC822 compliant), or an array of recipients,
     *              each RFC822 valid.
     *
     * @return mixed An array of forward paths (bare addresses) or a PEAR_Error
     *               object if the address list could not be parsed.
     * @access private
     */
    function parseRecipients($recipients)
    {
        include_once 'Mail/RFC822.php';

        // if we're passed an array, assume addresses are valid and
        // implode them before parsing.
        if (is_array($recipients)) {
            $recipients = implode(', ', $recipients);
        }

        // Parse recipients, leaving out all personal info. This is
        // for smtp recipients, etc. All relevant personal information
        // should already be in the headers.
        $addresses = Mail_RFC822::parseAddressList($recipients, 'localhost', false);

        // If parseAddressList() returned a PEAR_Error object, just return it.
        if (is_a($addresses, 'PEAR_Error')) {
            return $addresses;
        }

        $recipients = array();
        if (is_array($addresses)) {
            foreach ($addresses as $ob) {
                $recipients[] = $ob->mailbox . '@' . $ob->host;
            }
        }

        return $recipients;
    }

}
0

I'll remember to refer back to this if I have any more problems. Thank you Zagga!

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.