Email piping with php script - php

Hi' I want to forward all the emails(which are come to my inbox) to php script and retrieve email content and save it in a file. So do that I was add email forwarder with piping path correctly.
Address to Forward :tickets#ana.stage.centuryware.org
Pipe to a Program : /home/centuryw/public_html/stage/ana/osticket/upload/api/pipe.php
I have used following script as pipe.php
#!/usr/bin/php –q
<?
/* Read the message from STDIN */
$fd = fopen("php://stdin", "r");
$email = ""; // This will be the variable holding the data.
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
/* Saves the data into a file */
$fdw = fopen("mail.txt", "w+");
fwrite($fdw, $email);
fclose($fdw);
/* Script End */
But there was no output file and all email are bounced to my inbox again. Can anyone help me please?

Make sure the PHP file has the execute bit set (i.e. chmod +x pipe.php).

I know this question is 2 years old but hopefully this will help anybody who stumbles across it as I did.
I had exactly the same issue and I spent ages trying to log errors etc. I then noticed that my script (and this one) had PHP short tags (i.e. <?) and my PHP config file had these turned off. I changed the tag to <?php and the script worked! Obvious but easy to miss...

try the following 2 options to check:
First, your php file must need to have execute permission(from owner group at least), otherwise it won't work.
What did you used when you were using forwarder? You need to mention php compiler path at the beginnig also.
I have recently written an article regarding the full detail process of piping email content to php program , you will may like to have a look. Let me know if you have any more question. Thanks.

Chanaka -
This doesn't address why there is no output file, but...
Don't you want to use a+ in your fopen() call? The w+ argument will delete any content that already exists in your output file.
PS: Have you tried doing a simple test which writes to the output file using dummy text (not the input from an e-mail) as the contents?
Jeff Cohan

I encountered the same problem. However I solved it by specifying the output file with full path name. Instead of just 'mail.text', i entered '/home/username/public_html/mail.txt'.

If this is actually an email box, why not use IMAP (PHP)? There are lots of classes to read the mail with imap # phpclasses.org

Related

PHP replace a row in csv works fine on my localhost but does not replace the row when uploaded to cpanel?

Hello I am relatively new to PHP and I was trying to replace a row in a csv file, i didnt find an optimal solution so I concocted script (a work around) which suits my needs for the time being till I grasp a better understanding of PHP
I tested it on my localhost using XAMPP and everything was working fine , it was replacing the row as intended but when i uploaded the files to my cpanel it stopped replacing and instead it just goes the normal route and write the row on new line.
this is my code :
$fileName = 'Usecase.csv'; //This is the CSV file
$tempName = 'temp.csv';
$inFile = fopen($fileName, 'r');
$outFile = fopen($tempName,'w');
while (($line = fgetcsv($inFile)) !== FALSE)
{
if(($line[0] == "$fin") ) //Here I am checking the value of the variable to see if same value exists in the array then i am replacing the array which will be later written into the csv file
{
$line = explode (",", "$tempstr10");
$asd=$asd+1; //this is the variable that i defined and assigned value 0 in the top most section, this is used later in the code
}
fputcsv($outFile, $line );
}
fclose($inFile);
fclose($outFile);
unlink($fileName);
rename($tempName, $fileName);
if( $asd==0 && filesize("Usecase.csv")>0) // here its checking if the value is 0 , if value is 0 then that means the above code didnt execute which means the value wasnt present in the file , this is to avoid writing the same string again into the file
{ file_put_contents("Usecase.csv", "$tempstr10\r\n",FILE_APPEND | LOCK_EX); }
if( $asd==0 && filesize("Usecase.csv")==0)
{ file_put_contents("Usecase.csv", "$tempstr10\r\n",FILE_APPEND | LOCK_EX); }
and as I mentioned above , its working on the localhost but not on the cpanel , can someone point out if something is wrong with the code ? or if its something else ?
thank you
The most likely problem is that your local version of PHP or your local configuration of PHP is different from what is on the server.
For example, fopen is a feature that can be disabled on some shared servers.
You can check this by creating a php file with the following conents:
<?php phpinfo();
Then visit that PHP file in your browser. Do this for both your local dev environment and your cPanel server to compare the configuration to identify the differences that may be contributing to the differing behavior.
You should also check the error logs. They can be found in multiple different places depending on how your hosting provider has things configured. If you can't find them, you'll need to ask your hosting provider to know for sure where the error logs are.
Typical locations are:
The "Errors" icon in cPanel
A file named "error_log" in one of the folders of your site. Via ssh or the Terminal icon in cPanel you can use this command to find those files: find $PWD -name error_log
If your server is configured to use PHP-FPM, the php error log is located at ~/logs/yourdomain_tld.php.error.log
You should also consider turning on error reporting for the script by putting this at the very top. Please note that this should only be used temporarily while you are actively debugging the application. Leaving this kind of debugging output on could expose details about your application that may invite additional security risks.
<?php
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
... Your code here ...

Save the console text into a txt file? (PHP)

actual I finished writing my program. Because it is only a plugin and it runs on a external server I still want to see if I get some errors or something else in the console.
I wrote every console input with echo ...;. My question now is if it is possible to get the text of the console?
Because then I could easily safe it in a .txt file and could get access to it from the web :) - Or is there another way to get the console text?
I could probably just say fwrite(...) instand of echo ...;. But this will cost a lot of time...
Greetings and Thank You!
An alternative that could be usefull on windows would be to save all the output buffer to a txt, first check your php configuration for the console app implicit_flush must be off then
<?php
ob_start(); //before any echo
/** YOUR CODE HERE **/
$output = ob_get_contents(); //this variable has all the echoes
file_put_contents('c:\whatever.txt',$output);
ob_flush(); //shows the echoes on console
?>
If your goal is to create a text file to access, then you should create a text file directly.
(do this instead of echoing to console)
$output = $consoleData . "\n";
$output .= $moreConsoleData . "\n";
(Once you've completed that, just create the file:)
$file = fopen('output.txt', 'a');
fwrite($file, $output);
fclose($file);
Of course, this is sparse - you should also check that the file exists, create it if necessary, etc.
For console (commando line interface) you can redirect the output of your script:
php yourscript.php > path-of-your-file.txt
If you haven't access to a command line interface or to edit the cronjob line, you can duplicate the starndar output at the begining of the script:
$fdout = fopen('path-to-your-script.txt', 'wb');
eio_dup2($fdout, STDOUT);
eio_event_loop();
fclose($fdout);
(eio is an pecl extension)
If you are running the script using the console (i.e. php yourscript.php), you can easily save the output my modifying your command to:
php yourscript.php > path/to/log.txt
The above command will capture all output by the script and save it to log.txt. Change the paths for your script / log as required.

Outputting an echo statement to another page without running the first page

I'm using PHPMailer, and have a test.php file. Whenever this page is reloaded in the browser, the test.php file executes and sends email messages and echoes the email addresses that were used. I have a cronjob setup for this to execute once a day. I created another file body.php, that includes this:
<?php
$homepage = file_get_contents('http://www.myrealsite.com/mailer/test.php');
echo $homepage;
?>
This returns the information that I want, which is basically just an output of who I emailed, but here is the problem: Every time I reload body.php it executes the test.php file and sends email again. I want to be able to reload body.php without it running body.php. I'm new at this.
You can get body.php to load without sending the e-mail by adding a parameter to your call to body.php:
http://whatever.your.server.is/body.php?send=no
Then, you just need to $_GET that param and implement a simple IF:
if (!$_GET['send'] != 'no'){
//send the e-mail
Okay I figured it out. My cronjob was initially this:
0 17 * * * php /var/www/html/mailer/test.php >> /var/www/html/mailer/cron_status.log
This would execute the test.php file everyday at 5pm and write to this cron_status.log file. By Removing one > and changing the cronjob to:
0 17 * * * php /var/www/html/mailer/test.php > /var/www/html/mailer/cron_status.log
deletes whats in the cron_status.log and writes to it. Then for body.php I just used:
$emailLog = file_get_contents("http://www.bartdangus.com/mailer/cron_status.log");
echo $emailLog;
Now obviously it would be better to have a log file loge everything, but my requirement that I needed to meet does not include logging everything, I just needed what happened in the past 24hrs.
Whenever you run body.php it will make http request to test.php and so it will send email. If I understand you correctly you wish to list all the email addresses to whom the email was sent when Cron Job ran.
So it would be better if you save the results in a separate text file and then in body.php read that file. Like this, in your cron file (test.php):
$yourFile = fopen("email_logs.txt", "a"); //make sure this file is writeable by php
$fileContents = date('Y-m-d H:i:is')."\r\n"; //write the time of file saved
$fileContents .= 'email_address_here'; //all email addresses here
$fileContents .= '\r\n=======\r\n'; //a separator line.
fwrite($yourFile, "\n". $fileContents);
fclose($yourFile);
In your other file to read the emails, do:
$emailLog = file_get_contents("http://www.myrealsite.com/mailer/email_logs.txt");
What you're asking is impossible. You can't run a file that contains phpmailer code using file_get_contents() and using it in a cron job. You can, but that's why it's not working for you in the way you hoped it would.
It's one or the other.
Sidenote: The method and array used to catch the addresses of each email is unknown.
So, base yourself on the following, which writes to a file and reads from it, and checks if the file first exists.
body.php
<?php
if(file_exists('/path/to/email_sent_to.txt')){
$show_emails = file_get_contents('/path/to/email_sent_to.txt');
echo $show_emails;
}
Your cron job file and to the effect of:
<?php
// your phpmailer code
$emails = array("email1#example.com", "email2#example.com", "email3#example.com");
foreach($emails as $value) {
$value = $value . "\n";
$file = fopen("email_sent_to.txt", "a");
fwrite($file, $value);
fclose($file);
}
which the above will write to file as:
email1#example.com
email2#example.com
email3#example.com
Footnotes:
You may want to use a date/time format for your file naming convention, otherwise that file may get rather large over time. This is just a suggestion.
I.e.:
$prefix = "email_logs_";
$date = date('Y-m-H');
$time = date('h_i_s');
$logfile = $prefix . $date . "_" . $time . ".log";
which would create something like email_logs_2016-05-23_11_59_40.log.
Then read your file based on the most currently written file using PHP's filemtime() function.
http://php.net/manual/en/function.filemtime.php
Borrowed from this question and using a different approach while using a date/time file naming convention as I already suggested you do:
How to get the newest file in a directory in php
$files = scandir('logfiles', SCANDIR_SORT_DESCENDING);
$newest_file = $files[0];

Using php to write to a log file

First of I am very very very very bad with php so sorry for this question
I have an application in which i would like to log some debug data
and through my project i make a webrequest to my site storing the information in
$msg i then want to write the data to my logfile.log on the site.
i first used fopen fwrite fclose, but heard that file_put_contents would be better
especially as i very likely will have several users trying to write to the file at once.
Here's the code:
$msg = $_GET['w'];
$logfile= 'logfile.log';
echo file_put_contents($logfile,$msg, FILE_APPEND | LOCK_EX);
But as you might guess the code does nothing for me
i got it working with fopen fwrite fclose
but i wanted to add each user to a new line.
If any smart brain out there would help me I would appreciate it a ton.
Regards.
EDIT:
#Jay
This is how i tried applying it (opening php on the first line)
EDIT: removed 'tag' from code due to a copy/paste error.
error_reporting(E_ALL); ini_set('display_errors', 1)
$msg = $_GET['w'];
$logfile= 'logfile.log';
echo file_put_contents($logfile,$msg, FILE_APPEND | LOCK_EX);
Why not just use error_log()? With the message_type set to 3 (second parameter) the message will be written the the file specified in the third parameter:
$message = $_GET['w'];
$logfile = 'logfile.log';
// Debug: A line for verifying I have the message
echo "Writing message '$message' to logfile<br>";
error_log($message."\n", 3, $logfile);
// Debug: read back the log file to verify thatthe line has been written
readfile($logfile);
Note the newline appended to the message as error_log() doesn't do this for you.
Note also that permissions must be set to allow the web server to write to the target file. This is true whether using error_log() or file_put_contents()
PHP reference is here

PHP write to included file

I need to include one PHP file and execute function from it.
After execution, on end of PHP script I want to append something to it.
But I'm unable to open file. It's possible to close included file/anything similar so I'll be able to append info to PHP file.
include 'something.php';
echo $somethingFromIncludedFile;
//Few hundred lines later
$fh = fopen('something.php', 'a') or die('Unable to open file');
$log = "\n".'$usr[\''.$key.'\'] = \''.$val.'\';';
fwrite($fh, $log);
fclose($fh);
How to achieve that?
In general you never should modify your PHP code using PHP itself. It's a bad practice, first of all from security standpoint. I am sure you can achieve what you need in other way.
As Alex says, self-modifying code is very, VERY dangerous. And NOT seperating data from code is just dumb. On top of both these warnings, is the fact that PHP arrays are relatively slow and do not scale well (so you could file_put_contents('data.ser',serialize($usr)) / $usr=unserialize(file_get_contents('data.ser')) but it's only going to work for small numbers of users).
Then you've got the problem of using conventional files to store data in a multi-user context - this is possible but you need to build sophisticated locking queue management. This usually entails using a daemon to manage the queue / mutex and is invariably more effort than its worth.
Use a database to store data.
As you already know this attempt is not one of the good ones. If you REALLY want to include your file and then append something to it, then you can do it the following way.
Be aware that using eval(); is risky if you cannot be 100% sure if the content of the file does not contain harmful code.
// This part is a replacement for you include
$fileContent = file_get_contents("something.php");
eval($fileContent);
// your echo goes here
// billion lines of code ;)
// file append mechanics
$fp = fopen("something.php", "a") or die ("Unexpected file open error!");
fputs($fp, "\n".'$usr[\''.$key.'\'] = \''.$val.'\';');
fclose($fp);

Categories