data will be reset after fwrite with serialize php - php

I'm trying to save all daily visitors IP addresses in text file. Problem is, i don't know why after some IP addresses, all IP's will be remove!

I guess you are running with errors turned off or not looking at the php error log.
You missed a [] on the $FileIPs['TIME'] line.
Unless you have written a function called Write(), in which case show us the code for it, I dont know of a PHP function called Write(). So you are probably not actually writing the data back to the file anyway.
You used file_get_contents to read the file, why not use file_put_contents to rewrite it, like so.
//Add New IP To File
if($NewVisitor){
$FileIPs['TIME'][] = $Today;
$FileIPs['HISTORY'][] = $IP;
print_r($FileIPs);
//Write Function
file_put_contents(FILE_HISTORY, serialize($FileIPs));
}

Related

Strange result of stripos function

I run this code:
var_dump(stripos($virtualhost[1], "cold="));
echo '----------------------<br>';
var_dump($virtualhost[1]);
And I get the following result:
bool(false)
----------------------<br>
string(206) "<virtual-mta vmta1-cold=\"\">
bla-bla-bla\"
As you can see, the first var_dump directly contradicts the second. What can this be connected with, and how to avoid or circumvent this?
UPD (closer to reality):
<virtual-mta vmta1-cold="">
<domain *="">
dkim-sign yes
dkim-algorithm rsa-sha256
max-msg-rate 1000000/d
max-cold-virtual-mta-msg 1000000/d
</domain>
smtp-source-host there is a certain IP there is a certain domain
</virtual-mta>
For those who are experiencing a similar problem.
In my case, perhaps the point was that I got my array from the contents of the file, which, in turn, was received from the ssh-stream. Here's what I did: I saved this file to local hosting and opened it in notepad. And I saw that the contents of the file are different from my output!
Where I have
<virtual-mta vmta1-cold="">
There was a local file
<virtual-mta vmta1-cold>
... and a few more differences.
My goal was to identify the paragraphs, where after vmta comes this 'cold'. Then I decided to start from the contents of the local file and instead of looking for the cold= fragment I started looking for the -cold> fragment. And it worked.

Manipulate PHP-Files before they are parsed

I have managed to write a small, compilable extension for php, that prints "test" on every ZEND_RINIT.
I tested it with an php-file that loads multiple other files, which again load others [...]. The problem is, that the extension just prints "test" once, so I assume it does not fire each time a new file is loaded, how can i get my extension to do so?
Also the event is fired before the file is loaded, that is what i want, but therefore zend_get_executed_filename() is empty and I am not able to get the file content...
My final goal is to validate each file before executing the script. I planned on doing so by validating a file signature that is appended to the file.
Pseudocode Validation:
decrypt(signature, rsa.pub) = sha(filecontent)
Pseudocode Signing:
signature = encrypt(sha(filecontent), rsa.priv)
file += signature
Or is there an even better way to validate the files (i want them to be signed) before executing the script in them?
Thanks in advance!
ZEND_RINIT is called on request startup, that is when you execute your php-file. It will never be called again during execution of your PHP file. Only on next startup.
You have to find a way to hook into all of the file load functions of PHP.

Host file, log download, and host stats via PHP?

I'm a .NET guy attempting a PHP thing here, so am totally out of my comfort zone right now. What I THINK I want to do is to have 3 files:
download.php:
(a) contains a lookup of IDs to filenames (so download.php?file=11 querystring tells me I should host abc.zip)
(b) Some code to log this download to stats.log
(c) A couple header() calls and a readfile() call, similar to the answer to this question
stats.log: A simple log file that might look like the following example. This allows for logging to be accomplished by simply appending a line of text yet allows me to condense it from time to time.
abc.zip 1234
xyz.zip 4321
abc.zip 1
abc.zip 1
abc.zip 1
xyz.zip 1
abc.zip 1
stats.php: This is ultimately the PHP file that serves the stats. They can be real-time or near real-time, perhaps re-reading the file every minute and caching it or whatever. I don't really care and this won't be hit all that often but I do need to make sure that this isn't a stupidly expensive operation. This need not be a pretty page. Something so a human can easily read it is all that matters, so no fancy requirements there. For the above example of stats.log, I'd like this to serve something like the following:
abc.zip: 1238 downloads
xyz.zip: 4322 downloads
Ultimately, I don't want a database or any other systems involved in this. I only have FTP access to the server, so I can't really do much other than place scripts into the directory. I realize that I'll need to make sure that the script has write permissions to stats.txt, which is fine.
So my questions. I have a number of them but I believe they're all quite easy for somebody who knows PHP.
I think I have the hosting portion of download.php understood by setting headers and using readfile. However, how could I have a collection of key/value pairs representing file ids and filenames? If I were in .NET, I could do something like: var foo = new Dictionary<int, string> {{11, "abc.zip"}, {12, "xyz.zip"}} but I don't have a clue what this looks like in PHP.
How do I get querystrings? I need to pull from the URL "stuff/download.php?file=11" and take the 11 to grab my "abc.zip" out of my lookup collection.
How do I write the newline to my stats.log file?
How do I loop through my stats.log file in my stats.php script to count up and host these stats?
Bonus question: How do I cache the results from step 4 and only read the file once every minute/hour/or whatever?
I can probably fill in some gaps if somebody can answer at least most of these questions, but help sure would be appreciated! :)
1- You are looking for array e.g.
$files=array(11=>'abc.zip',
12=>'xyz.zip');
2- The Query String is accessed by the super global $_GET, so in your case $_GET['file'] holds that data you are interested in.
3,4,5
I would recommend storing the information JSON encoded. e.g.
$rawInfo=file_get_contents('stats.log');
$Info=json_decode($rawInfo,true);
if(isset($Info[$_GET['file']])){
$Info[$_GET['file']]++;
}else{
$Info[$_GET['file']]=1;
}
$rawInfo=json_encode($Info);
$h=fopen('stats.log','c');// If $h is false, you couldn't open the file
flock($h,LOCK_EX);// lock the file
$b=fwrite($h,$rawInfo);// if $b is not greater than 0, nothing was written
flock($h,LOCK_UN);
fclose($h);
//And then actually serve the file requested
This has the advantage of storing the information already in a useful format.
Whenever you fetch out the json_decodeed data, it is in the format of an array, which you will need to know how to handle.
stats.php might look something like this:
$rStats=file_get_contents('stats.log');
$Stats=json_decode($rStats,true);
foreach($Stats as $k=>$v){
echo $k.': '.$v.' download'.($v==1?'':'s');
}
I could have never done this so easily without #Shad's help in the accepted answer. As such, I wanted to post my final solution here that should work for practically anybody. This allows "direct links" (i.e. no 301/302 or other kinds of redirects) to function properly (right-click -> save as works too) while still logging downloads. NOTE that this is fairly "resource heavy" and some shared hosts may get upset with using something like this but as far as I can tell, this shouldn't really be a major drain. My files I'll be hosting are ~3-15MB and won't have a TON of downloads, so I'm not too worried about this in my scenario but if you use this solution, be very aware of this fact!
download.php:
<?php
$fileLookup = array(
0=>'subdir/test.zip',
1=>'another/sub/dir/test2.zip'
);
$currentRelativeFileName = $fileLookup[$_GET['file']];
$currentFileName = basename($currentRelativeFileName);
$rawInfo=file_get_contents('stats.log');
$Info=json_decode($rawInfo,true);
if(isset($Info[$currentFileName])){
$Info[$currentFileName]++;
}else{
$Info[$currentFileName]=1;
}
$rawInfo=json_encode($Info);
$h=fopen('stats.log','c');// If $h is false, you couldn't open the file
flock($h,LOCK_EX);// lock the file
$b=fwrite($h,$rawInfo);// if $b is not greater than 0, nothing was written
flock($h,LOCK_UN);
fclose($h);
header("Content-type: application/octet-stream");
header("Content-disposition: attachment; filename=" . $currentFileName);
readfile($currentRelativeFileName);
?>
stats.php:
<html>
<head>
<title>Here are my stats!</title>
</head>
<body>
<?php
$rStats=file_get_contents('stats.log');
if (strlen($rStats) > 5){
$Stats=json_decode($rStats,true);
foreach($Stats as $k=>$v){
echo $k.': '.$v.' download'.($v==1?'':'s') . '<br />';
}
}else{
echo 'No downloads';
}
?>
</body>

passing URL variables to exec() with php

I have a dedicated server that I use to crunch lots of data. The way I have it now, I can open a script with a process ID like example.php?ex_pid=123 and just let it go. It downloads a small portion of data, processes it, then uploads it into a database then starts again.
Ideally, I would like to call example.php?ex_pid=123 directly and not by passing a variable to example.php like exec('./example.php'.' '.EscapeShellArg($variable)); to keep it from acting globally.
I don't care about the output, if it could execute in the background, that would be brilliant. The server is an Ubuntu distribution btw.
Is this even possible? If so, any help and examples would be more then appreciated.
You could do something like:
exec("./example.php '".addslashes(serialize($_GET))."');
And then in example.php do something like this:
count($_GET) == 0 && $_GET = unserialize(stripslashes($_SERVER['argv'][1]))
The main issue with that is that ?ex_pid is GET data which is generally associated with either including the file or accessing it through a browser. If you were including the file or accessing it from a web browser this would be trivial, but running it as CLI, your only option would be to pass it as an argument, unfortunately. You can pass it as ex_pid=123 and just parse that data, but it would still need to be passed as an argument but doing that you could use parse_str() to parse it.
Depending on what the script does, you could call lynx to call the actual page with the get data attached and generate a hash for an apikey required to make it run. Not sure if that is an option, but it is another way to do it how you want.
Hope that helps!
I had a real problem with this and couldn't get it to work running something like example.php?variable=1.
I could however get an individual file to run using the exec command, without the ?variable=1 at the end.
What I decided to do was dynamically change the contents of a template file , depending on the variables I wanted to send. This file is called template.php and contains all the code you would normally run as a $_GET. Instead of using $_GET, set the value of the variable right at the top. This line of code is then searched and replaced with any value you choose.
I then saved this new file and ran that instead.
In the following example I needed to change an SQL query - the template file has the line $sql="ENTER SQL CODE HERE";. I also needed to change the value of a a variable at the top.
The line in template.php is $myvar=999999; The code below changes these line in template.php to the new values.
//Get the base file to modify - template.php
$contents=file_get_contents("template.php");
$sql="SELECT * FROM mytable WHERE foo='".$bar."'";
$contents=str_replace("ENTER SQL CODE HERE",$sql,$contents);
//Another search
$contents=str_replace("999999",$bar,$contents);
$filename="run_standalone_code".$bar.".php";
//If the file doesnt't exist, create it
if(!file_exists($filename)){
file_put_contents($filename, $contents);
}
//Now run this file
$cmd="/usr/local/bin/php ".$filename." >/dev/null &";
exec($cmd);
I had completely forgotten about this question until #Andrew Waugh commented on it (and I got an email reminder).
Anyways, this question stemmed from a misunderstanding as to how the $argv array is communicated to the script when using CLI. You can pretty much use as many arguments as you need. The way I accomplish this now is like:
if (isset($argv)) {
switch ($argv[1]) {
case "a_distinguishing_name_goes_here":
$pid = $argv[2];
sample_function($pid);
break;
case "another_name_goes_here":
do_something_else($argv[2]);
break;
}
}

PHP : Passing a file to a USer defined function

I have a PHP page(registration.php) from where i would submit a file to another form(preocess.php) .So that in the next page that page will send that file as an attachment to an email id. Can i Call a function in another file and pass this file to that function ?
It is some think like passing a stream to a function. (I am not sure .) Can anyone guide me on this ?
Absolutely, just include the file that originally calls the function.
<?php include ('file_with_function.php'); ?>
Should not pass a file around, better to handle it in the background.
store the file
put some id (in worst case the path) into session
forward the user to the next step (process.php)
Better yet to review and refactor the code if necessary to make the processing in one step.
This way you can avoid half-processed things, entry to the processing pipeline in the middle and similar common multi-page form handling problems.
If you're trying to email the file to someone, PHPMailer (http://phpmailer.codeworxtech.com/index.php?pg=methods) has a function addAttachment that works really well.
If you're just trying to process the file in some way, file_get_contents will get the content of the file as a string, which can be useful if it's text. You do, however, need to be careful that it's a small file, otherwise you'll run out of memory pretty quickly.

Categories