TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 03-21-2009, 02:31 AM   #1 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default Help search through file....

Hey guys, I need to read through my apache error_log file and filter out only what I'm looking for. (specific IP addresses)

Below is the normal format in the file:


192.168.2.1 - - [20/Mar/2009:21:03:38 -0400] "GET /index.php HTTP/1.1" 200 58
192.168.2.3 - - [20/Mar/2009:21:03:38 -0400] "GET /index.php HTTP/1.1" 200 58
192.168.2.3 - - [20/Mar/2009:21:03:38 -0400] "GET /index.php HTTP/1.1" 200 58
192.168.2.5 - - [20/Mar/2009:21:03:38 -0400] "GET /index.php HTTP/1.1" 200 58
192.168.2.5 - - [20/Mar/2009:21:03:38 -0400] "GET /index.php HTTP/1.1" 200 58
192.168.2.1 - - [20/Mar/2009:21:03:38 -0400] "GET /index.php HTTP/1.1" 200 58



Here's my code but it doesn't seem to work right?

What I'm trying to do is, as I read through the file, output anything that matches in the array....

Code:
<?php

	$bad_ip_address = array('192.168.2.1','192.168.2.3');

	$fh = fopen("error_log",'r');


			    		while (!feof($fh)) {
			        		$buffer = fgets($fh, 4096);

    									if(in_array("$bad_ip_address", $buffer))  {
											echo $buffer;
											}			
    						}
    	fclose($fh);

?>
So based on the array, my output should be:


192.168.2.1 - - [20/Mar/2009:21:03:38 -0400] "GET /index.php HTTP/1.1" 200 58
192.168.2.3 - - [20/Mar/2009:21:03:38 -0400] "GET /index.php HTTP/1.1" 200 58
192.168.2.3 - - [20/Mar/2009:21:03:38 -0400] "GET /index.php HTTP/1.1" 200 58
192.168.2.1 - - [20/Mar/2009:21:03:38 -0400] "GET /index.php HTTP/1.1" 200 58
allworknoplay is offline  
Reply With Quote
Old 03-21-2009, 07:13 AM   #2 (permalink)
The Frequenter
Newcomer 
 
xenon's Avatar
 
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 438
Thanks: 3
xenon is on a distinguished road
Default

Try this way:

PHP Code:
if(preg_match('/^(?:' str_replace('.''\.'implode('|'$bad_ip_address)) . ')/'$buffer) > 0) echo $buffer
$bad_ip_address is an array, so in your statement, it wouldn't work, because the word "Array" would be checked against the $buffer variable (which, btw, is a string, not an array, so the search would not work).
__________________
I have optimistic thoughts, even though sometimes (if not always) life's a bitch.
xenon is offline  
Reply With Quote
The Following User Says Thank You to xenon For This Useful Post:
allworknoplay (03-21-2009)
Old 03-21-2009, 11:39 AM   #3 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
Salathe is on a distinguished road
Default

If you want simple, perhaps something along the lines of the following would suffice.

PHP Code:
$bad_ips = array('12.34.56.78''127.0.0.1');
$fp fopen('apache.log''r');
while ( ! 
feof($fp))
{
    
$line fgets($fp4096);
    
$ip   substr($line0strpos($line' '));
    if (
in_array($ip$bad_ips))
    {
        echo 
$line;
    }
}
fclose($fp); 
Or you could go the OOP route with a little SPL goodness.

PHP Code:
class ApacheFilter extends FilterIterator
{
    protected 
$filter;
    
    public function 
__construct(Iterator $it$filter)
    {
        
parent::__construct($it);
        
$this->filter = (array) $filter;
    }
    
    public function 
accept()
    {
        
$line $this->getInnerIterator()->current();
        
$ip   substr($line0strpos($line' '));
        return (bool) 
in_array($ip$this->filter);
    }
}

$file   = new SplFileObject('apache.log');
$filter = new ApacheFilter($file, array('12.34.56.78''127.0.0.1'));
foreach (
$filter as $line)
{
    echo 
$line;


Last edited by Salathe : 03-21-2009 at 03:59 PM.
Salathe is offline  
Reply With Quote
The Following User Says Thank You to Salathe For This Useful Post:
allworknoplay (03-21-2009)
Old 03-21-2009, 03:24 PM   #4 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Thanks to both you guys!

I am going to attempt Sal's OOP way since I'm trying to learn OOP, might as well start with this...

I'll give it a shot and see how it turns out!
allworknoplay is offline  
Reply With Quote
Old 03-21-2009, 03:51 PM   #5 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

It's amazing how much shorter the procedural way is.

But I know what the power of OOP can bring to me if I keep at it.....
allworknoplay is offline  
Reply With Quote
Old 03-21-2009, 04:09 PM   #6 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Hey Salathe,

I am getting this error when I run it.


Quote:
Fatal error: Uncaught exception 'RuntimeException' with message 'SplFileObject::__construct(error.log): failed to open stream: No such file or directory' in /usr/storage/testphp/read_error_log.php:21
Stack trace:
#0 /usr/storage/testphp/read_error_log.php(21): SplFileObject->__construct('error.log')
#1 {main}
thrown in /usr/storage/testphp/read_error_log.php on line 21
allworknoplay is offline  
Reply With Quote
Old 03-21-2009, 05:08 PM   #7 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
Salathe is on a distinguished road
Default

The error says that there is no such file or directory called "error.log". Is the error.log file in the same directory as the script?
Salathe is offline  
Reply With Quote
The Following User Says Thank You to Salathe For This Useful Post:
allworknoplay (03-21-2009)
Old 03-21-2009, 06:25 PM   #8 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Quote:
Originally Posted by Salathe View Post
The error says that there is no such file or directory called "error.log". Is the error.log file in the same directory as the script?

Ohhh I am such a fool!! The name of my file is called: error_log

And I called the file: error.log hahaha..

That's what happens when you roll out of bed and the coffee doesn't kick in yet and you try to program...

It works now perfectly!!!

If you don't mind, I am going to try attempt to comment on your code and if you can be so kind to point out where I may be wrong?

I want to make sure I understand this OOP stuff....
allworknoplay is offline  
Reply With Quote
Old 03-21-2009, 07:06 PM   #9 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Ok Salathe:

Here is my attempt at commenting your code. Please let me know where I am wrong. Also, the method accept(), if you can explain that further because I don't see that called anywhere??

Thanks!!

Code:
<?php

	/* Create custom class called ApacheFilter that extends from existing
	class FilterIterator from PHP's built-in SPL */
	
	class ApacheFilter extends FilterIterator
{
    
    /* This is a protected property only available to the ApacheFilter class methods */
    protected $filter;
    
    /* This is the class's main construct. It accepts 2 attributes. Type casting the "$it" with Iterator?  */
    public function __construct(Iterator $it, $filter)
    {
        /* You are passing the "$it" attribute to the static parent??? */
        parent::__construct($it);
        
        /* You are passing this attribute to the class pointer "filter". Type casted as array? */
        $this->filter = (array) $filter;
    }
			
			/* Create a method accessible outside of the class */
			public function accept()
    {
        /* NEED HELP UNDERSTANDING THIS */
        $line = $this->getInnerIterator()->current();
        
        /* substr function. Take the first part of the line that is before the space ''  
        Start at the beginning of the line and up to the space ''
        */
        $ip   = substr($line, 0, strpos($line, ' '));
        
        /* If TRUE, return the line that has the IP address found in the array */
        return (bool) in_array($ip, $this->filter);
    }
}

/* This is the object we create to access the file we want to read */
$file   = new SplFileObject('error_log');

/* This is the object we create to access the ApacheFilter class and its methods.
We pass the newly created file object and array data */

$filter = new ApacheFilter($file, array('206.107.147.230', '75.149.134.235'));


/* This is just a simple array loop to echo out our data */
foreach ($filter as $line)
{
    echo $line;
}
allworknoplay is offline  
Reply With Quote
Old 03-21-2009, 10:11 PM   #10 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
Salathe is on a distinguished road
Default

  • Create custom class called ApacheFilter that extends from existing class FilterIterator from PHP's built-in SPL
    Absolutely correct.

  • This is a protected property only available to the ApacheFilter class methods
    Whilst this is true, it's also important to note that any classes extending from ApacheFilter will be able to define and modify this property. Compare that to declaring it as 'private'.

  • This is the class's main construct. It accepts 2 attributes. Type casting the "$it" with Iterator?
    It does not cast the $it argument at all. The term to use is 'type hinting' and declares that this argument should implement the Iterator interface. Failing to pass an iterator as the argument will generate a "Catchable fatal error" stating that "Argument 1 passed to ApacheFilter::__construct() must implement interface Iterator".

  • You are passing the "$it" attribute to the static parent???
    This is calling the parent class's constructor. In the case that we define our own behaviour with a custom __construct method, we need to manually call the parent's constructor if we want to use it. Essentially it's calling FilterIterator's __construct method. More info.

  • You are passing this attribute to the class pointer "filter". Type casted as array?
    Yes, the value is type casted to an array (for example, if only a string is provided it will be converted to an array containing that string). The array is assigned to the filter property of the class for use later.

  • Create a method accessible outside of the class
    Yes.

  • NEED HELP UNDERSTANDING THIS
    This is some of the OOP magic inherited from the FilterIterator and beyond. Remember the iterator that we passed along when creating the instance of our class? Well, the getInnerIterator method retrieves that iterator (our SplFileObject) for us. We then call the current method on that iterator (our SplFileObject) to retrieve the current line of the file. The terminology used for stringing multiple method calls together is 'method chaining' which is an incredibly useful (and easy to misuse!) feature introduced for us in PHP5 (not sure if you've seen or used chaining before).

  • substr function. Take the first part of the line that is before the space '' Start at the beginning of the line and up to the space ''
    Yes. In these Apache logs, the IP address is always at the start of the line and followed by a space character.

  • If TRUE, return the line that has the IP address found in the array
    This line returns TRUE if the IP address matches one in the filter array, FALSE otherwise: this is the purpose of the accept method (see below). The type casting to bool is only there so that I (or you, or anyone else reading it) can quickly see that the function returns a boolean TRUE/FALSE (which in_array does by default) and isn't strictly necessary.

  • This is the object we create to access the file we want to read
    Yep. SplFileObject is a utility class which can read and write files, and access useful information about them, in a variety of ways. More info.

  • This is the object we create to access the ApacheFilter class and its methods. We pass the newly created file object and array data
    Yes.

  • This is just a simple array loop to echo out our data
    Yes. Note that since we're iterating over the filter, only our filtered lines get echoed. This is where the accept method comes in to play. The accept method is automatically called as the foreach loop goes through each line. It defines which lines should be accepted or not (by returning TRUE/FALSE respectively) and is therefore where we place our filtering code.
Salathe is offline  
Reply With Quote
The Following User Says Thank You to Salathe For This Useful Post:
allworknoplay (03-22-2009)
Old 03-22-2009, 02:15 AM   #11 (permalink)
The Gregarious
 
allworknoplay's Avatar
 
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
allworknoplay is on a distinguished road
Default

Quote:
Originally Posted by Salathe View Post
  • Create custom class called ApacheFilter that extends from existing class FilterIterator from PHP's built-in SPL
    Absolutely correct.

  • This is a protected property only available to the ApacheFilter class methods
    Whilst this is true, it's also important to note that any classes extending from ApacheFilter will be able to define and modify this property. Compare that to declaring it as 'private'.

  • This is the class's main construct. It accepts 2 attributes. Type casting the "$it" with Iterator?
    It does not cast the $it argument at all. The term to use is 'type hinting' and declares that this argument should implement the Iterator interface. Failing to pass an iterator as the argument will generate a "Catchable fatal error" stating that "Argument 1 passed to ApacheFilter::__construct() must implement interface Iterator".

  • You are passing the "$it" attribute to the static parent???
    This is calling the parent class's constructor. In the case that we define our own behaviour with a custom __construct method, we need to manually call the parent's constructor if we want to use it. Essentially it's calling FilterIterator's __construct method. More info.

  • You are passing this attribute to the class pointer "filter". Type casted as array?
    Yes, the value is type casted to an array (for example, if only a string is provided it will be converted to an array containing that string). The array is assigned to the filter property of the class for use later.

  • Create a method accessible outside of the class
    Yes.

  • NEED HELP UNDERSTANDING THIS
    This is some of the OOP magic inherited from the FilterIterator and beyond. Remember the iterator that we passed along when creating the instance of our class? Well, the getInnerIterator method retrieves that iterator (our SplFileObject) for us. We then call the current method on that iterator (our SplFileObject) to retrieve the current line of the file. The terminology used for stringing multiple method calls together is 'method chaining' which is an incredibly useful (and easy to misuse!) feature introduced for us in PHP5 (not sure if you've seen or used chaining before).

  • substr function. Take the first part of the line that is before the space '' Start at the beginning of the line and up to the space ''
    Yes. In these Apache logs, the IP address is always at the start of the line and followed by a space character.

  • If TRUE, return the line that has the IP address found in the array
    This line returns TRUE if the IP address matches one in the filter array, FALSE otherwise: this is the purpose of the accept method (see below). The type casting to bool is only there so that I (or you, or anyone else reading it) can quickly see that the function returns a boolean TRUE/FALSE (which in_array does by default) and isn't strictly necessary.

  • This is the object we create to access the file we want to read
    Yep. SplFileObject is a utility class which can read and write files, and access useful information about them, in a variety of ways. More info.

  • This is the object we create to access the ApacheFilter class and its methods. We pass the newly created file object and array data
    Yes.

  • This is just a simple array loop to echo out our data
    Yes. Note that since we're iterating over the filter, only our filtered lines get echoed. This is where the accept method comes in to play. The accept method is automatically called as the foreach loop goes through each line. It defines which lines should be accepted or not (by returning TRUE/FALSE respectively) and is therefore where we place our filtering code.

Wow I cannot thank you enough. The Thank You button only let's me click on it once...

I've read about 3-4 books on OOP the last 2 months. My favorite is this one: The Object-Oriented Thought Process by Matt Wiesfeld.

Maybe you've read it or heard of it, but I like that it's not PHP related but just the overall thought process of OO design.

Anyways, this OO stuff is taking a long time for it to sink in for me. Especially things like method overloading, and the many types of design patterns.

Thanks again and I am still going to look at your code so I fully understand it.

In all the books I've read, I don't recall reading up on Method chaining so I'll have to do some digging on that, sounds pretty important!!! (unless there's another term out there for method chaining?)
allworknoplay is offline  
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads
Thread Thread Starter Forum Replies Last Post
Where is my file? superthin General 3 07-25-2009 09:48 AM
Txt based login with 3 different or more password file to search in or list ? Peuplarchie Absolute Beginners 1 07-27-2008 06:48 PM
Aptana Jaxer and file uploads xenon Advanced PHP Programming 2 06-06-2008 10:22 AM
Writing to XML file buildakicker General 8 02-06-2008 08:17 PM
how to search the content of txt file meshi Absolute Beginners 11 11-01-2007 04:43 PM


All times are GMT. The time now is 07:44 AM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design