Page 1 of 2
class with only static functions
Posted: Thu Jan 19, 2006 12:17 pm
by jonathant
In my application I am performing lots of random search queries. I need to run these queries without actually instantiating objects, for example "how many users have last name 'Smith'". In this case it seems like static functions are my best option, other than just creating a query right there on the page.
Some could probably be thrown into existing classes as static functions, but those classes are starting to get pretty big. So, I'm thinking about creating a class called "datasearch" or something like that, and just putting all these random static functions in it. Is this good/bad practice? Should I stick to trying to find the closest matching class and putting the static functions in it? I'm still learning how to do oop, so am I missing something fundamental?
Also, I'm curious to know how big (loc, or filesize) are your biggest files? Some of my scripts are getting pretty big, but I'm a beginner so I don't know what really big is. Maybe, they're still relatively small?
Posted: Thu Jan 19, 2006 12:38 pm
by Christopher
I get the sense from your comments about static calls, the size of your code and wondering where methods should go that you are perhaps coding in a procedural fashion using the OO constructs in PHP. And, just my opinion, but I try to stay away from static calls because they really eliminate polymorphism -- although there are uses for them.
Maybe if you showed some example code we could give some specific comments.
Posted: Thu Jan 19, 2006 1:20 pm
by Jenk
PEAR::DB can be used statically as well as instantiated.
In other words, there are no problems creating methods that are specifically for static purposes. One of those reasons can be adhoc SQL statements.
Posted: Thu Jan 19, 2006 5:20 pm
by jonathant
Jenk wrote:In other words, there are no problems creating methods that are specifically for static purposes. One of those reasons can be adhoc SQL statements.
Yes, this is what I was getting at, and adhoc SQL statements is exactly the reason I need the class. Lets say, for example, I have a User class that is getting pretty bulky. I need a way to find all users with the last name "Smith." So, rather than add yet another function to the User class, I want to create a whole new class that would just have a static function search_last_name(). And because there are many more random searches, I want to be able to add these as more static functions to the class, for example, search_first_name(). In the end, I have a class that is built entirely of static methods. I guess I was just wondering if there were any pitfalls to this, or if there was something I was overlooking that would make it bad practice.
Also, what about file sizes?
Posted: Thu Jan 19, 2006 5:47 pm
by Christopher
Jenk wrote:PEAR::DB can be used statically as well as instantiated.
In other words, there are no problems creating methods that are specifically for static purposes. One of those reasons can be adhoc SQL statements.
As you can tell I'm not a big fan if static methods, so I don't think much of PEAR DB's design.
jonathant wrote:Also, I'm curious to know how big (loc, or filesize) are your biggest files? Some of my scripts are getting pretty big, but I'm a beginner so I don't know what really big is. Maybe, they're still relatively small?
It sounds like there are somelarger problems with the design of your classes. I'd be interested to see some code. Perhaps another approach might work better than to keep adding functions.
Posted: Fri Jan 20, 2006 4:27 am
by Jenk
Why, may I ask, are you not a fan of them?
The good thing to a static class, with static methods is that they are "grouped" together.. need a method for abstracting data from a DB? Look in the DB class.. etc.

Posted: Fri Jan 20, 2006 10:50 am
by Maugrim_The_Reaper
If a method can be called statically though surely its limited in how it can interact with the rest of the package - can't say I've looked at PEAR::DB closely (being an ADOdb fan) but it would seem having too many methods static would limit their overall functionality for purposes aside from the core "do sql, return results"...
I can't see such a design being too popular in most places... Smells too much like procedural.
Posted: Fri Jan 20, 2006 3:57 pm
by Christopher
Jenk wrote:Why, may I ask, are you not a fan of them?
I think
Maugrim_The_Reaper give a sense when he says. "Smells too much like procedural." For me, the main thing I have against static calls is that they eliminate the possiblity of polymorphism, which for me is one of the best things about OO. I have found over the years that I tend to get rid of static calls because, though they seem simpler at first, eventually they are an inflexible point in the code that I start designing around. I know there are cases where they simplify the code a little -- so I don't want to sound like some OO zealot saying they are verboten. But for me they are ususally an example of where I haven't got the design right yet because I can't see the bigger picture. For others they may fit in better with the way they code.
Jenk wrote:The good thing to a static class, with static methods is that they are "grouped" together.. need a method for abstracting data from a DB? Look in the DB class.. etc.

I'm not sure about "grouped together" but it sounds like a function library to me. Nothing wrong with helper functions. Other languages with namespaces allow you to group things without creating a class.
As for PEAR DB, I am not a fan of the static factory that they use. It's just unnecessary overhead that allows for something that I have never done -- switch types of database servers on the fly. For me, because that code is only is one place in my applications, there is no difference between class DBConnection('MySQL', ...) and class DBConnectionMySQL(...) except less overhead.
Posted: Fri Jan 20, 2006 4:46 pm
by Jenk
They don't eliminate polymorphism at all:
Code: Select all
class WhatEver
{
function StaticSomething ()
{
if (func_num_args() > 2) {
return self::doSomethingA(func_get_args());
} else {
return self::doSomethingB(func_get_args());
}
}
}
With PHP5+ you can declare a method static, thus it doesn't become part of your instantiated objects, so the overheads are not increased much, if at all..
If anything, it's the collaboration of related functions that make static classes worthwhile, as said earlier, you group the functions together that perform similar tasks so you know where they are (Separation.. Layers.. Patterns..) Take a look at feyd's SHA256 class for a good example.
Posted: Fri Jan 20, 2006 5:21 pm
by Christopher
Jenk wrote:They don't eliminate polymorphism at all:
Not sure if different return values is polymorphism.
Jenk wrote:If anything, it's the collaboration of related functions that make static classes worthwhile, as said earlier, you group the functions together that perform similar tasks so you know where they are (Separation.. Layers.. Patterns..)
Again, that sounds like a function library not a class to me. I get te sense that "static" is mostly used to create Singletons which I try to stay away from as well.
Jenk wrote:Take a look at feyd's SHA256 class for a good example.
I would like to -- where can I see it?
Posted: Fri Jan 20, 2006 5:30 pm
by feyd
it's in Code Snippets..

Posted: Fri Jan 20, 2006 7:56 pm
by Ambush Commander
Posted: Fri Jan 20, 2006 9:23 pm
by Christopher
feyd wrote:it's in Code Snippets..

I have to say that the code is really excellent. And, I think it is an example of how you can use classes to namespace helper functions. However I think it overdoes the interface a little. There is too much of the following for my taste:
Code: Select all
$func = 'hash' . $mode;
$ret = SHA256::$func($data);
//and
$type = 'SHA256Message' . $type;
$this->message =& new $type( $str );
Separate, simpler, direct interfaces for strings, files and URLs would be preferable to me. I think it would make the code clearer.
Posted: Fri Jan 20, 2006 9:50 pm
by feyd
arborint wrote:Separate, simpler, direct interfaces for strings, files and URLs would be preferable to me. I think it would make the code clearer.
Ahem.
Code: Select all
* Function:
* SHA256::hash()
*
* Syntax:
* string SHA256::hash( string message[, string format ])
*
* Description:
* SHA256::hash() is intended to hash a single string, of nominal length
* (memory permitting.) The entire string is loaded into memory, broken
* into chunks and appended with the hashing fill algorithm.
*
* SHA256::hash() is a static function that must be called with `message`
* and optionally `format`. Possible values for `format` are:
* 'hex' default; hexidecimal string output (lower case)
* 'HEX' hexidecimal string output (upper case)
* 'bin' binary string output
* 'bit' bit level output (256 character '1' & '0' string)
*
* Failures return FALSE.
*
* Usage:
* $hash = SHA256::hash('string to hash');
*
* ---------------------------------
*
* Function:
* SHA256::hashFile()
*
* Syntax:
* string SHA256::hashFile( string filename[, string format ])
*
* Description:
* SHA256::hashFile() is intended to hash a local file _only_. STDIN is
* not supported at this time, nor is any other protocol other than 'file.'
*
* SHA256::hashFile() is a static function that must be called with a
* `filename` and optionally `format`. Possible values for `format` are:
* 'hex' default; hexidecimal string output (lower case)
* 'HEX' hexidecimal string output (upper case)
* 'bin' binary string output
* 'bit' bit level output (256 character '1' & '0' string)
*
* Failures return FALSE.
*
* Usage:
* $hash = SHA256::hashFile('/path/to/file.ext');
*
* Note:
* This function will not accept any other protocols other than 'file'.
* This is due to the use of fstat(), among other reasons.
*
* ---------------------------------
*
* Function:
* SHA256::hashURL()
*
* Syntax:
* string SHA256::hashURL( string url[, string format ])
*
* Description:
* SHA256::hashURL() is intended to hash a url. 'http://' is optional, if
* you want to use it. The function checks if allow_url_fopen is enabled.
* If it is, the url is passed through fopen(), so all protocols supported
* your installation of PHP are supported automatically. If allow_url_fopen
* is off, fsockopen is attempted to be used. This version only supports
* http requests through fsockopen. So beware.
*
* SHA256::hashURL() is a static function that must be called with a `url`
* and optionally `format`. Possible values for `format` are:
* 'hex' default; hexidecimal string output (lower case)
* 'HEX' hexidecimal string output (upper case)
* 'bin' binary string output
* 'bit' bit level output (256 character '1' & '0' string)
*
* Failures return FALSE.
*
* If a protocol is not specified, 'http' is assumed.
*
* Usage:
* $hash = SHA256::hashURL('http://www.site.com');
*
* Note:
* The protocol used _must_ be registered with your PHP with
* allow_url_fopen enabled, or must be 'http'.

Posted: Fri Jan 20, 2006 10:51 pm
by Christopher
feyd wrote:Ahem.
I know, I know. What I meant was that I probably would of implemented it as:
SHA256String::hash()
SHA256File::hash()
SHA256URL::hash()
That way you actually get polymorphism and I think it would simplify the code somewhat.
However I should say that I have a lot of respect for your abilities and it is easy to nitpick complex code, so it is quite possible that yours is the best solution to problem. As I have said above, a lot if this has to do with ones opinion of statics, Singletons, etc.