• geoffrey, MCP, PMP (unregistered)

    Aside from TRWTF, which is using PHP when there are so many superior Microsoft alternatives available, I'm not really seeing a problem.

    I'm a big proponent of wrapping framework functions like this. You never know when you might need to pop in some logging or embed some business logic at this level. At which point, wrapping it early saves a lot of code changes in the future.

  • Martin D (unregistered)

    A comment on every line is not "well commented" code.

  • big picture thinker (unregistered)

    I can't believe so many of you are ok with this code. It certainly does not improve maintainability. People who work on this code in the future will not be expecting it. And if a particular function he's encapsulating does eventually become depreciated, they'll still have to CTRL+F for it and change it. Encapsulating functions just for consistency in naming convention is plain stupid. It increases clutter, file size, execution overhead, and confusion.

    CAPTCHA: nulla. Your arguments are nulla and void.

  • onitake (unregistered)

    Oh. And I thought this post was about ponies...

  • foo (unregistered) in reply to ubersoldat
    ubersoldat:
    Jonathan:
    $meToo++;

    Seriously, whose kneecaps do I break for DEPRECATING split()? I'm a little surprised that Rasmus made it out of Penguicon with all his extremities a couple of years back. Anyone starting a new project in PHP in this day and age is either drunk or mismanaged.

    Shit! Didn't know this. Haven't touched PHP with a pole since version 3 and believe me, I'm not turning back.

    Anyway, if anyone thinks this is a good idea, it's because we're talking about PHP here people. In any other sane language you wouldn't have to worry about lossing base64... shit, Java have had Vector deprecated for 20 years but you can still use it.

    Please contact our HR department. We're looking for experts with 20+ years Java experience. 15 years of C-Pound would help, too.

  • AN AMAZING CODER (unregistered) in reply to corroded
    corroded:
    steve:
    seems like a great way to fix deprecated methods in the future....

    Bingo. I've seen a sysadmin trawling through code to fix PHP removing a method that was used throughout the system. Now, admittedly he shouldn't have upgraded PHP without checking better... but having a wrapper for the function would have meant a single change rather than searching the entire code base for the method.

    Apparently all of you that believe this is the best (or even a good) way to handle it have never heard of grep or sed/awk.

    Should he wrap every php function that could possibly change in the future, even those implementing agnostic algorithms? Whatever would he do if PHP died one day? Oh the horror.

  • (cs)

    I haven't yet seen the right implementation, so I've just written my own. It follows some nice patterns and is, of course, easy to extend. The code is mostly self-documenting so I didn't bother to write elaborate comments. Have fun with it!

    <?php
    //=====================================================================
    // Wrapper code for base64_encode and base64_decode
    // Requires PHP 5.3 or up
    //---------------------------------------------------------------------
    
    
    /**
     * Interface for function library
     */
    interface IFunctionLib {
    	public function registerFunction($name, $implementation);
    	public function unregisterFunction($name);
    	public function callFunction($name, $arguments);
    	public function __call($name, $arguments);
    }
    
    /**
     * Abstract function library implementation
     */
    abstract class AbstractFunctionLib implements IFunctionLib {
    }
    
    /**
     * Basic function library implementation
     */
    class BasicFunctionLib extends AbstractFunctionLib {
    	private $_functions;
    	
    	public function __construct() {
    		$this->_functions = array();
    	}
    	
    	public function registerFunction($name, $implementation) {
    		$this->_assertNameValid($name);
    		$this->_assertNameAvailable($name);
    		$this->_assertImplementationValid($implementation);
    		
    		$this->_functions[$name] = $implementation;
    	}
    	
    	public function unregisterFunction($name) {
    		$this->_assertNameValid($name);
    		$this->_assertNameKnown($name);
    		
    		unset($this->_functions[$name]);
    	}
    	
    	public function callFunction($name, $arguments) {
    		$this->_assertNameKnown($name);
    		
    		$function = $this->_functions[$name];
    		
    		return call_user_func_array($function, $arguments);
    	}
    	
    	public function __call($name, $arguments) {
    		return $this->callFunction($name, $arguments);
    	}
    
    	protected function _assertNameValid($name) {
    		if(empty($name)) {
    			throw new \Exception("Function name must not be empty");
    		}
    		
    		if(!is_string($name)) {
    			throw new \Exception("Function name must be a string");
    		}
    	}
    
    	protected function _assertNameAvailable($name) {
    		if(isset($this->_functions[$name])) {
    			throw new \Exception("A function with the name '$name' has already been registered");
    		}
    	}
    	
    	protected function _assertNameKnown($name) {
    		if(!isset($this->_functions[$name])) {
    			throw new \Exception("Unknown function '$name'");
    		}
    	}
    	
    	protected function _assertImplementationValid($implementation) {
    		if(!is_callable($implementation)) {
    			throw new \Exception("Implementation must be callable");
    		}
    	}
    }
    
    
    
    /**
     * Interface for function library wrapper
     */
    interface IFunctionLibWrapper {
    	public function __call($name, $arguments);
    }
    
    /**
     * Abstract function library wrapper implementation
     */
    abstract class AbstractFunctionLibWrapper implements IFunctionLibWrapper {
    	abstract public function __construct(AbstractFunctionLib $functionLib);
    }
    
    /**
     * Basic function library wrapper implementation
     */
    class BasicFunctionLibWrapper extends AbstractFunctionLibWrapper {
    	protected $_functionLib;
    	
    	public function __construct(AbstractFunctionLib $functionLib) {
    		$this->_functionLib = $functionLib;
    	}
    	
    	public function __call($name, $arguments) {
    		return $this->_functionLib->callFunction($name, $arguments);
    	}
    }
    
    /**
     * Basic base64 function library wrapper implementation
     */
    class BasicBase64Implementation extends BasicFunctionLibWrapper {
    	public function __construct() {
    		$functionLib = new BasicFunctionLib();
    		
    		$encodeFunction = new BasicBase64EncodeFunction();
    		$functionLib->registerFunction('encode', $encodeFunction);
    		
    		$decodeFunction = new BasicBase64DecodeFunction();
    		$functionLib->registerFunction('decode', $decodeFunction);
    		
    		parent::__construct($functionLib);
    	}
    }
    
    
    
    /**
     * Interface for function object
     */
    interface IFunction {
    	public function __invoke();
    }
    
    /**
     * Abstract function object implementation
     */
    abstract class AbstractFunction implements IFunction {
    	abstract public function __construct($name);
    }
    
    /**
     * Abstract PHP function object implementation
     */
    abstract class PhpFunction extends AbstractFunction {
    	protected $_name;
    
    	public function __construct($name) {
    		$this->_name = $name;
    	}
    	
    	public function __invoke() {
    		$arguments = func_get_args();
    		
    		return call_user_func_array($this->_name, $arguments);
    	}
    	
    	private function _assertFunctionExists($name) {
    		if(!function_exists($name)) {
    			throw new \Exception("Function '$name' does not exist");
    		}
    	}
    }
    
    /**
     * Basic base64 encode function object implementation
     */
    class BasicBase64EncodeFunction extends PhpFunction {
    	const FUNCTION_NAME = 'base64_encode';
    	
    	public function __construct() {
    		parent::__construct(static::FUNCTION_NAME);
    	}
    }
    
    /**
     * Basic base64 decode function object implementation
     */
    class BasicBase64DecodeFunction extends PhpFunction {
    	const FUNCTION_NAME = 'base64_decode';
    	
    	public function __construct() {
    		parent::__construct(static::FUNCTION_NAME);
    	}
    }
    
    
    
    /**
     * Interface for implementation factory
     */
    interface IImplementationFactory {
    	public function getDefaultImplementation();
    }
    
    /**
     * Abstract implementation factory implementation
     */
    abstract class AbstractImplementationFactory implements IImplementationFactory {
    	public function __construct() {}
    }
    
    /**
     * Base64 implementation factory implementation
     */
    class Base64ImplementationFactory extends AbstractImplementationFactory {
    	public function getDefaultImplementation() {
    		$base64 = new BasicBase64Implementation();
    		
    		return $base64;
    	}
    }
    
    
    
    /**
     * Interface for unit test
     */
    interface IUnitTest {
    	public function run();
    }
    
    /**
     * Abstract unit test implementation
     */
    abstract class AbstractUnitTest implements IUnitTest {
    }
    
    /**
     * Unit test implementation for the basic base64 function library wrapper implementation
     */
    class BasicBase64ImplementationUnitTest extends AbstractUnitTest {
    	const INPUT            = "this is a plain string";
    	const EXPECTED_ENCODED = "dGhpcyBpcyBhIHBsYWluIHN0cmluZw==";
    	const EXPECTED_DECODED = self::INPUT;
    
    	public function run() {
    		$base64ImplementationFactory = new Base64ImplementationFactory();
    		$base64Implementation        = $base64ImplementationFactory->getDefaultImplementation();
    		
    		$input   = self::INPUT;
    		$encoded = $base64Implementation->encode($input);
    		$decoded = $base64Implementation->decode($encoded);
    		
    		$truthMap = array(
    			true  => 'correct',
    			false => 'incorrect',
    		);
    		
    		echo "
    ";
    		echo "Input  : '$input'\n";
    		echo "Encoded: '$encoded' (" . $truthMap[$encoded === self::EXPECTED_ENCODED] . ")\n";
    		echo "Decoded: '$decoded' (" . $truthMap[$decoded === self::EXPECTED_DECODED] . ")\n";
    		echo "
    ";
    }
    

    }

    //===================================================================== // Test if implementation is working correctly //---------------------------------------------------------------------

    $basicBase64ImplementationUnitTest = new BasicBase64ImplementationUnitTest(); $basicBase64ImplementationUnitTest->run();

    ?>

  • AN AMAZING CODER (unregistered) in reply to geoffrey, MCP, PMP
    geoffrey:
    Aside from TRWTF, which is using PHP when there are so many superior Microsoft alternatives available, I'm not really seeing a problem.

    I'm a big proponent of wrapping framework functions like this. You never know when you might need to pop in some logging or embed some business logic at this level. At which point, wrapping it early saves a lot of code changes in the future.

    /**

    • The earth might not exist sometime in the future. Just incase, we can use this
    • method to determine if it does. */ function detectEarthStatus() { return true; }

    function getPostBody() { if( !detectEarthStatus() ) { //Do something there in the future that we have no idea about today } else {

       return sprintf( "This is called %s.  I suspect you have very %s experience working with    teams of talented %s and just like to impress your friends with %s.", "over-engineering", "little", "developers", "LOC" );
    }
    

    }

    echo "I wated all of that time wrapping everything in logic because I love to write code for the sake of writing code." . getPostBody();

  • Tractor (unregistered) in reply to ubersoldat
    ubersoldat:
    Jonathan:
    $meToo++;

    Seriously, whose kneecaps do I break for DEPRECATING split()? I'm a little surprised that Rasmus made it out of Penguicon with all his extremities a couple of years back. Anyone starting a new project in PHP in this day and age is either drunk or mismanaged.

    Shit! Didn't know this. Haven't touched PHP with a pole since version 3 and believe me, I'm not turning back.

    Anyway, if anyone thinks this is a good idea, it's because we're talking about PHP here people. In any other sane language you wouldn't have to worry about lossing base64... shit, Java have had Vector deprecated for 20 years but you can still use it.

    It's not about losing it. It's just for consistent naming convections, the comments on the function even says so.

  • BillClintonsThirdTerm (unregistered) in reply to frits
    frits:
    Seriously guys, what software dev isn't a phony?

    0/10

  • FragFrog (unregistered) in reply to rootkit
    rootkit:
    I haven't yet seen the right implementation, so I've just written my own. It follows some nice patterns and is, of course, easy to extend. The code is mostly self-documenting so I didn't bother to write elaborate comments. Have fun with it!
    [snip]

    Dude.. You write methods called "_assertNameKnown" and you forget to use assert, and you don't even specify an assert_callback? Obviously that was a rushed job, it could have been much more enterprisey!

  • np (unregistered) in reply to fritters
    fritters:
    Ronan:
    He should have made it generic.

    function call_php_function($function, $parameter){ //Initialisation of return value $return_value = '';

    //Call of the php function $return_value = $function($parameter);

    //let's return te result return $return_value; }

    No. The better way is to set up a mapping using an Excel spreadsheet, then generate an XML configuration file.

    Then your code just needs to parse the XML file and follow the translations. This way if you ever need to change them or add more, you don't even have to make code changes!

    It's brillant!

    You work at my company don't you? Seriously, that is what the proposition was for the project, and the management bought the story, promoted the staff.

    2 years later, and they don't like how it looks, so they are going to redo it. Same XML barf, just rewriting the framework, also writing legacy support. But instead of relying on the legacy support for existing tests, they will port all of them over as well. It should keep them busy for a couple years and improve the product by 0%.

  • (cs) in reply to FragFrog
    FragFrog:
    rootkit:
    I haven't yet seen the right implementation, so I've just written my own. It follows some nice patterns and is, of course, easy to extend. The code is mostly self-documenting so I didn't bother to write elaborate comments. Have fun with it!
    [snip]

    Dude.. You write methods called "_assertNameKnown" and you forget to use assert, and you don't even specify an assert_callback? Obviously that was a rushed job, it could have been much more enterprisey!

    Dang, I knew I was missing something! I keep learning a lot here at WTF, best practices and all. Will be included next time!

  • Jim Howard (unregistered)

    I can't belive I'm the only one who doesn't see what this developer is doing here.

    HE'S EVALUATED BY KLOC COUNT!!!!

    Do get the job his company HR wanted to know if he'd ever worked on a program with 10^^8 or more lines of code?

    His PHB had an intern write a script that reports lines of code/week/developer.

    He's doing what his boss is paying him for!

  • s73v3r (unregistered)

    Actually, given that PHP is not consistent in the least regarding how it names functions, let alone the order of parameters, a library that does a lot of this, and makes things sane and consistent, might be welcomed

  • geoffrey, MCP, PMP (unregistered) in reply to AN AMAZING CODER
    AN AMAZING CODER:
    geoffrey:
    Aside from TRWTF, which is using PHP when there are so many superior Microsoft alternatives available, I'm not really seeing a problem.

    I'm a big proponent of wrapping framework functions like this. You never know when you might need to pop in some logging or embed some business logic at this level. At which point, wrapping it early saves a lot of code changes in the future.

    /**

    • The earth might not exist sometime in the future. Just incase, we can use this
    • method to determine if it does. */ function detectEarthStatus() { return true; }

    function getPostBody() { if( !detectEarthStatus() ) { //Do something there in the future that we have no idea about today } else {

       return sprintf( "This is called %s.  I suspect you have very %s experience working with    teams of talented %s and just like to impress your friends with %s.", "over-engineering", "little", "developers", "LOC" );
    }
    

    }

    echo "I wated all of that time wrapping everything in logic because I love to write code for the sake of writing code." . getPostBody();

    I would do it like this:

    function detectEarthStatusWrapper(){ //May need to add code in the future return detectEarthStatus(); }

    function detectEarthStatus() { return true; }

    function getPostBody() { if( !detectEarthStatusWrapper() ) { //Do something there in the future that we have no idea about today } else { return sprintf( "This is called %s. I suspect you have very %s experience working with teams of talented %s and just like to impress your friends with %s.", "over-engineering", "little", "developers", "LOC" ); } }

  • Bill (unregistered) in reply to GotCred
    GotCred:
    Frist - and not SPAM
    What does oxymoron mean again?
  • Bill (unregistered) in reply to XXXXX
    XXXXX:
    I had a coworker who wanted to wrap everything. Our company has a set of common shared libraries for common functions. My coworker thought we should wrapper any calls to the company's common libraries from our project in our project's own utility functions. That way, if our company's internal software (our project) was ever moved to another company, it would be easy to swap in a different library.
    Ah yes, the Shim. I worked in a place where we put wrappers around cryptographic functions to provide a consistent interface. The idea was that if we changed the cryptographic software we used, we would simply change the wrapper function to call the new libraries. Unfortunatly what seemed to happen was:
    #include "vendor1.h"  //needed for vendor1RSAcall
    
    //Version 1
    ourRSAcall(some_parameters)
    {
      vendor1RSAcall(some_parameters);
    }
    

    *although in this example I pass some_parameters on, in reality the parameters would change (if in nothing else then in order) Then we wanted to use different libraries, but instead of modifying this wrapper, we insert another layer

    #include "vendor2.h" //needed for vendor2RSAcall
    
    //Implement Shim
    vendor1RSAcall(parameters)
    {
      vendor2RSAcall(parameters);
    }
    
    //Version 1
    ourRSAcall(some_parameters)
    {
      vendor1RSAcall(some_parameters);
    }
    

    When I worked there, there were 5 layers already (and as it was my first proper IT job, it didn't really occur to me until halfway through an implementation of yet another shim that perhaps we were doing it wrong - and who would have listened to me anyway?

    Now, I get upset when people even think about doing things this way.

  • BentFranklin (unregistered)

    If you want to standardize your php, couldn't you use cpp or emacs -batch?

  • Pick Me, Pick ME (unregistered) in reply to tweek
    tweek:
    frits:
    Jonathan:
    $meToo++;

    Seriously, whose kneecaps do I break for DEPRECATING split()? I'm a little surprised that Rasmus made it out of Penguicon with all his extremities a couple of years back. Anyone starting a new project in PHP in this day and age is either drunk or mismanaged.

    Direct string manipulation is so 1990s. Everyone knows the extra level of indirection added by using regular expressions adds more value.

    What's that old chestnut? Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have two problems.

    Now let's argue over who said that (first)...

  • Stir Pot (unregistered) in reply to Martin D
    Martin D:
    A comment on every line is not "well commented" code.
    Depends on how you define well.... Well Commented might mean good commenting Well Commented might mean liberally commented Well Commented might mean well, commented Well COmmented might mean commented with waterhole references...

    etc...

    There's a difference between well commented and well commented

  • dfgjh (unregistered) in reply to big picture thinker
    big picture thinker:
    I can't believe so many of you are ok with this code. It certainly does not improve maintainability. People who work on this code in the future will not be expecting it. And if a particular function he's encapsulating does eventually become depreciated, they'll still have to CTRL+F for it and change it. Encapsulating functions just for consistency in naming convention is plain stupid. It increases clutter, file size, execution overhead, and confusion.

    CAPTCHA: nulla. Your arguments are nulla and void.

    Assuming you're not a troll....

    you might still need the ol' Cntrl-F, but you'll only be replacing one instance not 567.834 of them

  • (cs) in reply to tweek

    Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have /^\d+$/ problems.

  • w (unregistered) in reply to AN AMAZING CODER
    AN AMAZING CODER:
    corroded:
    steve:
    seems like a great way to fix deprecated methods in the future....

    Bingo. I've seen a sysadmin trawling through code to fix PHP removing a method that was used throughout the system. Now, admittedly he shouldn't have upgraded PHP without checking better... but having a wrapper for the function would have meant a single change rather than searching the entire code base for the method.

    Apparently all of you that believe this is the best (or even a good) way to handle it have never heard of grep or sed/awk.

    Should he wrap every php function that could possibly change in the future, even those implementing agnostic algorithms? Whatever would he do if PHP died one day? Oh the horror.

    When PHP dies he has a future in VB...

    also 1)Some people develop on Widoze 2)Not sure a sed or awk approach is necessarily best either

  • wibble (unregistered) in reply to AN AMAZING CODER
    AN AMAZING CODER:
    corroded:
    steve:
    seems like a great way to fix deprecated methods in the future....

    Bingo. I've seen a sysadmin trawling through code to fix PHP removing a method that was used throughout the system. Now, admittedly he shouldn't have upgraded PHP without checking better... but having a wrapper for the function would have meant a single change rather than searching the entire code base for the method.

    Apparently all of you that believe this is the best (or even a good) way to handle it have never heard of grep or sed/awk.

    Should he wrap every php function that could possibly change in the future, even those implementing agnostic algorithms? Whatever would he do if PHP died one day? Oh the horror.

    he could scrape the php.net website from wayback machine for the timelines of various (all?) php functions over differing versions then and automatically generate the php wrappers code accordingly ... as a bonus if php/wayback machine died he'd just get a simple 404

  • sino (unregistered) in reply to Mikey
    Mikey:
    /* Frist function ** ** Just for consistency and ** ease of maintenance, let's declare our own function **/ function frist() {

    // Initialise output variable $output = "frist";

    // output the output echo $output; }

    You're genius.

  • sino (unregistered) in reply to GotCred
    GotCred:
    Frist - and not SPAM

    Your comment about nothing at all smells like spam.

  • sino (unregistered) in reply to Myth
    Myth:
    Frist?

    Akismet thinks this is spam. It probably is.

    I think of you as a genius.

  • sino (unregistered) in reply to Myth
    Myth:
    Myth:
    Frist?

    Akismet thinks this is spam. It probably is.

    Damn you Akismet. Three other comments while I battled you.

    Yup - you're definitely a genius.

  • sino (unregistered) in reply to XXXXX
    XXXXX:
    I had a coworker who wanted to wrap everything. Our company has a set of common shared libraries for common functions. My coworker thought we should wrapper any calls to the company's common libraries from our project in our project's own utility functions. That way, if our company's internal software (our project) was ever moved to another company, it would be easy to swap in a different library.

    Your coworker was a dumbass. Is he still doing that shit, wasting time and all?

  • sino (unregistered) in reply to Manadar
    Manadar:
    And in the end it turns out they actually needed a variant of base64. The new programmer only has to edit those two functions with the correct implementation.

    That's sometimes how those things work out. If you suspect your implementation of base64 is not what PHP offers, please please please, do something like this. Even if that means your implementation of base64 is not base64.

    There's only one base-64 encoding, dude. If you need something else, then don't fucking call it base-64.

  • sino (unregistered) in reply to Jeff
    Jeff:
    Looks like he wrapped the function to make it easier to fix if php updates end up changing the name or the method of calling it. Seems pretty standard to me. #ifdefs do this ALL THE TIME in C/C++ code to handle differences in compiler and architecture.

    What a lame excuse. When did any framework [that should be used] release anything that isn't back-compatible? If you name one, then you know which one you should not use.

  • sino (unregistered) in reply to Rootbeer
    Rootbeer:
    I can respect the intent to apply some consistency to the calling conventions for PHP's internal functions: some are underline_separated, some are camelCased, some lead with the subject, some with the verb, and no two functions that take haystack and needle parameters take them in the same order.

    These new function definitions still aren't very good, though. The code's needlessly explicit in a way that makes me believe the coder doesn't understand how 'return' works, and the comments are completely useless.

    Like it fucking matters what the naming style is (as long as it's readable). Give it up! We'll never agree to the same coding style, and give it the fuck up. Let me indent, (and you fucking don't, if that's what you like); let me begin my function names with a capital letter (and you fucking lowercase it, if that's what you like), etc.

  • sino (unregistered) in reply to Tractor
    Tractor:
    Anon:
    That's... somewhat pointless but not totally stupid.

    PHP is a notorious mess, and he's trying to build an abstraction layer on top of it. To improve the tool, really. It's the same thing framework developers are trying to do, just on a much smaller scale.

    Agreed, this is actually quite a sane thing to do. It keeps the function names consistent, god knows the PHP developers didn't.

    You're probably just another so-called developer who spends more time talking the talk instead of walking it. Go solve problems, vs talking about coding styles.

  • sino (unregistered) in reply to PedanticCurmudgeon
    PedanticCurmudgeon:
    Tractor:
    Anon:
    That's... somewhat pointless but not totally stupid.

    PHP is a notorious mess, and he's trying to build an abstraction layer on top of it. To improve the tool, really. It's the same thing framework developers are trying to do, just on a much smaller scale.

    Agreed, this is actually quite a sane thing to do. It keeps the function names consistent, god knows the PHP developers didn't.

    And you know a language is really bad when even the trolls about it raise good points.

    If PHP isn't back-compatible across its versions, then it's de-facto a joke platform.

  • sino (unregistered) in reply to foo
    foo:
    corroded:
    steve:
    seems like a great way to fix deprecated methods in the future....

    Bingo. I've seen a sysadmin trawling through code to fix PHP removing a method that was used throughout the system. Now, admittedly he shouldn't have upgraded PHP without checking better... but having a wrapper for the function would have meant a single change rather than searching the entire code base for the method.

    By the logic, why not wrap everything, functions, variables, constants, files, networks, character sets, just everything. Anything might change some day, after all, and spending some effort to adjust later is certainly worse that spending 10 times the effort now. Fuck performance, Moore's Law will take care of that, right?

    he-he. Then there'll be a guy wrapping your wrappers, in case they get changed.

    I totally agree with your sarcastic comment. Fuck the wrapper-happy coders. They just create clutter.

  • Raniz (unregistered) in reply to frits

    If you used split() you were either already using regular expressions or using the wrong method; explode() is the correct method to use if you don't need regular expressions.

    Besides, split() is merely deprecated (not removed), it echoes an E_DEPRECATION warning which should be shown on development servers and hidden on production servers.

  • Raniz (unregistered) in reply to frits
    frits:
    Jonathan:
    $meToo++;

    Seriously, whose kneecaps do I break for DEPRECATING split()? I'm a little surprised that Rasmus made it out of Penguicon with all his extremities a couple of years back. Anyone starting a new project in PHP in this day and age is either drunk or mismanaged.

    Direct string manipulation is so 1990s. Everyone knows the extra level of indirection added by using regular expressions adds more value.
    This is what my above comment was supposed to quote...

    Captcha: ACSI - the dyslexic sibling of ASCII

  • sino (unregistered) in reply to Martin D
    Martin D:
    A comment on every line is not "well commented" code.

    Commenting relatively readable code is for pussies. Comments should be used to explain the concept, business logic, and similar - and not to re-tell/rephrase what code statement already do. It's just clutter.

  • sino (unregistered) in reply to big picture thinker
    big picture thinker:
    I can't believe so many of you are ok with this code. It certainly does not improve maintainability. People who work on this code in the future will not be expecting it. And if a particular function he's encapsulating does eventually become depreciated, they'll still have to CTRL+F for it and change it. Encapsulating functions just for consistency in naming convention is plain stupid. It increases clutter, file size, execution overhead, and confusion.

    CAPTCHA: nulla. Your arguments are nulla and void.

    If you need a job, we're hiring.

  • sino (unregistered) in reply to AN AMAZING CODER
    AN AMAZING CODER:
    corroded:
    steve:
    seems like a great way to fix deprecated methods in the future....

    Bingo. I've seen a sysadmin trawling through code to fix PHP removing a method that was used throughout the system. Now, admittedly he shouldn't have upgraded PHP without checking better... but having a wrapper for the function would have meant a single change rather than searching the entire code base for the method.

    Apparently all of you that believe this is the best (or even a good) way to handle it have never heard of grep or sed/awk.

    Should he wrap every php function that could possibly change in the future, even those implementing agnostic algorithms? Whatever would he do if PHP died one day? Oh the horror.

    Yup. Let's also think about a way to wrap PHP code-block declarations (or whatever the proper name is), in case they change in the future. I'm talking about "<?php" here...

  • sino (unregistered) in reply to rootkit
    rootkit:
    I haven't yet seen the right implementation, so I've just written my own. It follows some nice patterns and is, of course, easy to extend. The code is mostly self-documenting so I didn't bother to write elaborate comments. Have fun with it!
    <?php
    //=====================================================================
    // Wrapper code for base64_encode and base64_decode
    // Requires PHP 5.3 or up
    //---------------------------------------------------------------------
    
    
    /**
     * Interface for function library
     */
    interface IFunctionLib {
    	public function registerFunction($name, $implementation);
    	public function unregisterFunction($name);
    	public function callFunction($name, $arguments);
    	public function __call($name, $arguments);
    }
    
    /**
     * Abstract function library implementation
     */
    abstract class AbstractFunctionLib implements IFunctionLib {
    }
    
    /**
     * Basic function library implementation
     */
    class BasicFunctionLib extends AbstractFunctionLib {
    	private $_functions;
    	
    	public function __construct() {
    		$this->_functions = array();
    	}
    	
    	public function registerFunction($name, $implementation) {
    		$this->_assertNameValid($name);
    		$this->_assertNameAvailable($name);
    		$this->_assertImplementationValid($implementation);
    		
    		$this->_functions[$name] = $implementation;
    	}
    	
    	public function unregisterFunction($name) {
    		$this->_assertNameValid($name);
    		$this->_assertNameKnown($name);
    		
    		unset($this->_functions[$name]);
    	}
    	
    	public function callFunction($name, $arguments) {
    		$this->_assertNameKnown($name);
    		
    		$function = $this->_functions[$name];
    		
    		return call_user_func_array($function, $arguments);
    	}
    	
    	public function __call($name, $arguments) {
    		return $this->callFunction($name, $arguments);
    	}
    
    	protected function _assertNameValid($name) {
    		if(empty($name)) {
    			throw new \Exception("Function name must not be empty");
    		}
    		
    		if(!is_string($name)) {
    			throw new \Exception("Function name must be a string");
    		}
    	}
    
    	protected function _assertNameAvailable($name) {
    		if(isset($this->_functions[$name])) {
    			throw new \Exception("A function with the name '$name' has already been registered");
    		}
    	}
    	
    	protected function _assertNameKnown($name) {
    		if(!isset($this->_functions[$name])) {
    			throw new \Exception("Unknown function '$name'");
    		}
    	}
    	
    	protected function _assertImplementationValid($implementation) {
    		if(!is_callable($implementation)) {
    			throw new \Exception("Implementation must be callable");
    		}
    	}
    }
    
    
    
    /**
     * Interface for function library wrapper
     */
    interface IFunctionLibWrapper {
    	public function __call($name, $arguments);
    }
    
    /**
     * Abstract function library wrapper implementation
     */
    abstract class AbstractFunctionLibWrapper implements IFunctionLibWrapper {
    	abstract public function __construct(AbstractFunctionLib $functionLib);
    }
    
    /**
     * Basic function library wrapper implementation
     */
    class BasicFunctionLibWrapper extends AbstractFunctionLibWrapper {
    	protected $_functionLib;
    	
    	public function __construct(AbstractFunctionLib $functionLib) {
    		$this->_functionLib = $functionLib;
    	}
    	
    	public function __call($name, $arguments) {
    		return $this->_functionLib->callFunction($name, $arguments);
    	}
    }
    
    /**
     * Basic base64 function library wrapper implementation
     */
    class BasicBase64Implementation extends BasicFunctionLibWrapper {
    	public function __construct() {
    		$functionLib = new BasicFunctionLib();
    		
    		$encodeFunction = new BasicBase64EncodeFunction();
    		$functionLib->registerFunction('encode', $encodeFunction);
    		
    		$decodeFunction = new BasicBase64DecodeFunction();
    		$functionLib->registerFunction('decode', $decodeFunction);
    		
    		parent::__construct($functionLib);
    	}
    }
    
    
    
    /**
     * Interface for function object
     */
    interface IFunction {
    	public function __invoke();
    }
    
    /**
     * Abstract function object implementation
     */
    abstract class AbstractFunction implements IFunction {
    	abstract public function __construct($name);
    }
    
    /**
     * Abstract PHP function object implementation
     */
    abstract class PhpFunction extends AbstractFunction {
    	protected $_name;
    
    	public function __construct($name) {
    		$this->_name = $name;
    	}
    	
    	public function __invoke() {
    		$arguments = func_get_args();
    		
    		return call_user_func_array($this->_name, $arguments);
    	}
    	
    	private function _assertFunctionExists($name) {
    		if(!function_exists($name)) {
    			throw new \Exception("Function '$name' does not exist");
    		}
    	}
    }
    
    /**
     * Basic base64 encode function object implementation
     */
    class BasicBase64EncodeFunction extends PhpFunction {
    	const FUNCTION_NAME = 'base64_encode';
    	
    	public function __construct() {
    		parent::__construct(static::FUNCTION_NAME);
    	}
    }
    
    /**
     * Basic base64 decode function object implementation
     */
    class BasicBase64DecodeFunction extends PhpFunction {
    	const FUNCTION_NAME = 'base64_decode';
    	
    	public function __construct() {
    		parent::__construct(static::FUNCTION_NAME);
    	}
    }
    
    
    
    /**
     * Interface for implementation factory
     */
    interface IImplementationFactory {
    	public function getDefaultImplementation();
    }
    
    /**
     * Abstract implementation factory implementation
     */
    abstract class AbstractImplementationFactory implements IImplementationFactory {
    	public function __construct() {}
    }
    
    /**
     * Base64 implementation factory implementation
     */
    class Base64ImplementationFactory extends AbstractImplementationFactory {
    	public function getDefaultImplementation() {
    		$base64 = new BasicBase64Implementation();
    		
    		return $base64;
    	}
    }
    
    
    
    /**
     * Interface for unit test
     */
    interface IUnitTest {
    	public function run();
    }
    
    /**
     * Abstract unit test implementation
     */
    abstract class AbstractUnitTest implements IUnitTest {
    }
    
    /**
     * Unit test implementation for the basic base64 function library wrapper implementation
     */
    class BasicBase64ImplementationUnitTest extends AbstractUnitTest {
    	const INPUT            = "this is a plain string";
    	const EXPECTED_ENCODED = "dGhpcyBpcyBhIHBsYWluIHN0cmluZw==";
    	const EXPECTED_DECODED = self::INPUT;
    
    	public function run() {
    		$base64ImplementationFactory = new Base64ImplementationFactory();
    		$base64Implementation        = $base64ImplementationFactory->getDefaultImplementation();
    		
    		$input   = self::INPUT;
    		$encoded = $base64Implementation->encode($input);
    		$decoded = $base64Implementation->decode($encoded);
    		
    		$truthMap = array(
    			true  => 'correct',
    			false => 'incorrect',
    		);
    		
    		echo "
    ";
    		echo "Input  : '$input'\n";
    		echo "Encoded: '$encoded' (" . $truthMap[$encoded === self::EXPECTED_ENCODED] . ")\n";
    		echo "Decoded: '$decoded' (" . $truthMap[$decoded === self::EXPECTED_DECODED] . ")\n";
    		echo "
    ";
    }
    

    }

    //===================================================================== // Test if implementation is working correctly //---------------------------------------------------------------------

    $basicBase64ImplementationUnitTest = new BasicBase64ImplementationUnitTest(); $basicBase64ImplementationUnitTest->run();

    ?>

    Please don't apply for jobs here.

  • sino (unregistered) in reply to dfgjh
    dfgjh:
    big picture thinker:
    I can't believe so many of you are ok with this code. It certainly does not improve maintainability. People who work on this code in the future will not be expecting it. And if a particular function he's encapsulating does eventually become depreciated, they'll still have to CTRL+F for it and change it. Encapsulating functions just for consistency in naming convention is plain stupid. It increases clutter, file size, execution overhead, and confusion.

    CAPTCHA: nulla. Your arguments are nulla and void.

    Assuming you're not a troll....

    you might still need the ol' Cntrl-F, but you'll only be replacing one instance not 567.834 of them

    Bigger troll are you, motherfucker - even assuming he IS one.

  • w (unregistered) in reply to sino
    sino:
    Tractor:
    Anon:
    That's... somewhat pointless but not totally stupid.

    PHP is a notorious mess, and he's trying to build an abstraction layer on top of it. To improve the tool, really. It's the same thing framework developers are trying to do, just on a much smaller scale.

    Agreed, this is actually quite a sane thing to do. It keeps the function names consistent, god knows the PHP developers didn't.

    Ah touche' You're probably just another so-called developer who spends more time talking the talk instead of walking it. Go solve problems, vs talking about coding styles.

  • Jimmy (unregistered)

    WOW. sino appears, abuses everyone for the hell of it, and then seems to think people would want to work with him....

  • (cs)

    Wouldn't it make more sense to write a wrapper AFTER a potentially troublesome PHP version change, effectively re-creating the old functions using their old names? No need to search through code to change, no need to write wrappers ahead of time.

  • (cs)

    I especially like the wasteful coding of the interior of the functions. Three lines when (even assuming a wrapper was justifiable) this would have done for base64Encode:

    function base64Encode($plain) {
      return base64_encode($plain);
    }
    

    Especially the initialization of $output, which was immediately overwritten, demonstrates a desperate lack of understanding of coding principles.

  • Jack (unregistered) in reply to Jimmy
    Jimmy:
    WOW. sino appears, abuses everyone for the hell of it, and then seems to think people would want to work with him....

    I was thinking the same thing. And then there was this:

    sino:
    dfgjh:
    big picture thinker:
    I can't believe so many of you are ok with this code. It certainly does not improve maintainability. People who work on this code in the future will not be expecting it. And if a particular function he's encapsulating does eventually become depreciated, they'll still have to CTRL+F for it and change it. Encapsulating functions just for consistency in naming convention is plain stupid. It increases clutter, file size, execution overhead, and confusion.

    CAPTCHA: nulla. Your arguments are nulla and void.

    Assuming you're not a troll....

    you might still need the ol' Cntrl-F, but you'll only be replacing one instance not 567.834 of them

    Bigger troll are you, motherfucker - even assuming he IS one.

    Who's the troll now?

  • (cs) in reply to foo
    foo:
    ubersoldat:
    Jonathan:
    $meToo++;

    Seriously, whose kneecaps do I break for DEPRECATING split()? I'm a little surprised that Rasmus made it out of Penguicon with all his extremities a couple of years back. Anyone starting a new project in PHP in this day and age is either drunk or mismanaged.

    Shit! Didn't know this. Haven't touched PHP with a pole since version 3 and believe me, I'm not turning back.

    Anyway, if anyone thinks this is a good idea, it's because we're talking about PHP here people. In any other sane language you wouldn't have to worry about lossing base64... shit, Java have had Vector deprecated for 20 years but you can still use it.

    Please contact our HR department. We're looking for experts with 20+ years Java experience. 15 years of C-Pound would help, too.

    Maybe "20 Years" is like the biblical "40 days and 40 nights" - ie "an unspecified amount of time"

  • (cs) in reply to dfgjh
    dfgjh:
    big picture thinker:
    I can't believe so many of you are ok with this code. It certainly does not improve maintainability. People who work on this code in the future will not be expecting it. And if a particular function he's encapsulating does eventually become depreciated, they'll still have to CTRL+F for it and change it. Encapsulating functions just for consistency in naming convention is plain stupid. It increases clutter, file size, execution overhead, and confusion.

    CAPTCHA: nulla. Your arguments are nulla and void.

    Assuming you're not a troll....

    you might still need the ol' Cntrl-F, but you'll only be replacing one instance not 567.834 of them

    Why would he need to fix that last 0.834 of them [/troll]

Leave a comment on “The Phony”

Log In or post as a guest

Replying to comment #:

« Return to Article