SitePoint Sponsor

User Tag List

Results 1 to 11 of 11
  1. #1
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    PHP, what inspires you?

    I was wondering, what problems have you come across that have made you rush to your IDE of choice and code away?

    I'm sure that I'm not the only one that needs a problem to solve before things become interesting. Given the nature of us forum folk, I would guess most of the long standing folk hang around, just waiting for a problem to solve.

    Here's mine tonight, I've spent a full night researching, learning, then solving this problem.

    Sometimes it's nice to be reminded why we stick at this stuff.

    So there I was, as usual, browsing Sitepoint and this feature really irked me. In conjunction with this thread, it seemed people were fine with a loop that constantly queried a database to see if a value already existed until they found one that didn't.

    It just screamed to breach DRY and I set about tonight finding a way to solve this.

    In the end, I created a class to encode the id provided by the database after record insertion (always unique) to generate this unique value (al la Short URL services).

    For completeness, here is class.
    PHP Code:
    <?php
    /**
     * @author Anthony Sterling
     */
    class Base62
    {
        
    /**
         * @desc    Holds the key used to encode and decode.
         *
         * @var        Array
         */
        
    protected static $aCharMap = array(
            
    'a''b''c''d''e''f''g''h',
            
    'i''j''k''l''m''n''o''p',
            
    'q''r''s''t''u''v''w''x',
            
    'y''z''A''B''C''D''E''F',
            
    'G''H''I''J''K''L''M''N',
            
    'O''P''Q''R''S''T''U''V',
            
    'W''X''Y''Z''0''1''2''3',
            
    '4''5''6''7''8''9'
        
    );

        
    /**
         * @desc    Encodes an integer to Base 62
         *
         * @param    Integer    $iInteger
         * @return    String
         */
        
    public static function Encode($iInteger)
        {
            
    $sString '';
            while(
    $iInteger 0)
            {
                
    $sString .= (string)self::$aCharMap[$iInteger 62];
                
    $iInteger floor($iInteger 62);
            }
            return 
    $sString;
        }

        
    /**
         * @desc    Decodes a Base 62 encoded string
         *
         * @param    String    $sString
         * @return    Integer
         */
        
    public static function Decode($sString)
        {
            
    $aFlippedMap array_flip(
                
    self::$aCharMap
            
    );
            
    $iInteger 0;
            for(
    $iCurrentPosition 0$iCurrentPosition strlen($sString); $iCurrentPosition++)
            {
                
    $iInteger += $aFlippedMap[$sString[$iCurrentPosition]] * pow(62$iCurrentPosition);
            }
            return 
    $iInteger;
        }
    }

    $iInteger 2147483647;
    $sEncoded Base62::Encode($iInteger);
    $iDecoded Base62::Decode($sEncoded);

    header('Content-Type: text/plain');
    printf(
        
    "
        Attempting to Encode:\t%d
        Encoded Value:\t\t%s
        Decoded Value:\t\t%s
        "
    ,
        
    $iInteger,
        
    $sEncoded,
        
    $iDecoded
    );
    /*
        Attempting to Encode:    2147483647
        Encoded Value:            bLMuvc
        Decoded Value:            2147483647
    */
    ?>
    So, have you had any moments like this? If so, what was the problem then approach/code did you apply to the problem in hand?

    Thanks all,

    Anthony.
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  2. #2
    SitePoint Guru silver trophy JamesColin's Avatar
    Join Date
    May 2009
    Location
    Jomtien, Pattaya, Thailand
    Posts
    910
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice way to think outside the box! Although I never tried to set up a url shortener, I've already thought about it and I too was thinking the random code was stored in the database and that to generate a new one would always mean checking if it wasn't already linked to an url in the database..
    With your way, the autoincrement ID is enough. Do you think all services such as tinyurl, bit.ly and such are doing like you came up with?
    Do you really need traffic? Where to? What for?
    If you really do need traffic then stop messing around!
    Advertise on my sites today: She Told Me & Best Reviewer :
    200,000+ UV / Month

  3. #3
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thanks James,

    With regards to your comment about short url services, I would guess they are, looking at a few of their URLs would indicate so anyway.

    My thinking was the only true unique value we could rely on easily would be the id provided by the database, hence my 'journey'.

    Although, upon reflection, I wonder whether vowels should be removed from the Map. Otherwise, a record with an ID of 3164521 might be quite the disappointment for the visitor!

    From my initial conceptions, indicated in this thread, to researching and working out a final solution felt great.

    Which then led me to wonder, what problems have other coders come across that similarly inspired them to code a solution...
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  4. #4
    SitePoint Guru risoknop's Avatar
    Join Date
    Feb 2008
    Location
    end($world)
    Posts
    834
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great class. Don't forget to add all URL safe characters to the $aCharMap, add these to get even shorter URLs:

    PHP Code:
    -_.*|()! 

  5. #5
    SitePoint Addict whydna's Avatar
    Join Date
    Jun 2006
    Posts
    258
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Why don't those URL shorteners just generate a GUID?

  6. #6
    SitePoint Guru
    Join Date
    Dec 2005
    Posts
    982
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by whydna View Post
    Why don't those URL shorteners just generate a GUID?
    A 36-64 length string isn't much of a shortener
    MySQL v5.1.58
    PHP v5.3.6

  7. #7
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by risoknop View Post
    Great class.
    Thanks!

    Quote Originally Posted by risoknop View Post
    Don't forget to add all URL safe characters to the $aCharMap, add these to get even shorter URLs:

    PHP Code:
    -_.*|()! 
    Feel free to abuse, maybe the addition of an abstract getMap() method? It would only take a little modification...
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  8. #8
    SitePoint Guru
    Join Date
    Dec 2005
    Posts
    982
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    yeah, your base simply becomes count(self::getMap()). Should be pretty easy to extend to whatever chars you want. Love the code SilverBulletUK
    MySQL v5.1.58
    PHP v5.3.6

  9. #9
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BrandonK View Post
    yeah, your base simply becomes count(self::getMap()). Should be pretty easy to extend to whatever chars you want.
    Sure, something like the following would do it, although it does need tweaking I would say...
    PHP Code:
    <?php
    abstract class BaseConverter
    {
        public function 
    encode($iInteger)
        {
            
    $aMap $this->getMap();
            
    $sString '';
            while(
    $iInteger 0)
            {
                
    $sString .= (string)$aMap[$iInteger count($aMap)];
                
    $iInteger floor($iInteger count($aMap));
            }
            return 
    $sString;
        }
        
        public function 
    decode($sString)
        {
            
    $aFlippedMap array_flip(
                
    $this->getMap()
            );
            
    $iInteger 0;
            for(
    $iCurrentPosition 0$iCurrentPosition strlen($sString); $iCurrentPosition++)
            {
                
    $iInteger += $aFlippedMap[$sString[$iCurrentPosition]] * pow(count($aFlippedMap), $iCurrentPosition);
            }
            return 
    $iInteger;
        }
        
        abstract public function 
    getMap();
    }

    class 
    Base62Converter extends BaseConverter
    {
        public function 
    getMap()
        {
            return array(
                
    'a''b''c''d''e''f''g''h',
                
    'i''j''k''l''m''n''o''p',
                
    'q''r''s''t''u''v''w''x',
                
    'y''z''A''B''C''D''E''F',
                
    'G''H''I''J''K''L''M''N',
                
    'O''P''Q''R''S''T''U''V',
                
    'W''X''Y''Z''0''1''2''3',
                
    '4''5''6''7''8''9'
            
    );
        }
    }
    ?>
    Quote Originally Posted by BrandonK View Post
    Love the code SilverBulletUK
    Gee, thanks.
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  10. #10
    Afraid I can't do that Dave Hal9k's Avatar
    Join Date
    Mar 2004
    Location
    East Anglia, England.
    Posts
    640
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I translated this class into Python and removed vowels from the encoding scheme to avoid inappropriate words.

    Code Python:
    from math import floor, pow
     
    class BaseConverter:
    	encoding_scheme =  'bcdfghjklmnpqrstvwxyzABCDFGHJKLMNPQRSTVWXYZ0123456789'
    	base = 0
     
    	def __init__(self):
    		self.base = len(self.encoding_scheme)
     
    	def encode(self, integer):
    		if integer < 0:
    			raise ValueError("Integer to encode must be positive")
    		encoded_string = ''
    		if integer == 0:
    			return self.encoding_scheme[0]
    		else:
    			while (integer > 0):
    				encoded_string = encoded_string + self.encoding_scheme[integer % self.base]
    				integer = int(floor(integer / self.base))
    		return encoded_string
     
    	def decode(self, encoded_string):
    		integer = 0
    		encoded_string_len = len(encoded_string)
     
    		for i in range(0, encoded_string_len):
    			integer += self.encoding_scheme.index(encoded_string[i]) * pow(self.base, i)
    		return int(integer)
     
     
    if __name__ == '__main__':
    	print 'Testing:'	
    	base = BaseConverter()
    	print '  encoding_scheme: ' + base.encoding_scheme
    	print '  Original: ' + str(2147483647)
    	print '  Encoded:  ' + base.encode(2147483647)
    	print '  Decoded:  ' + str(base.decode('zjKlkh'))
    	print '  Zero encode (print base.encode(0)): ' + base.encode(0) 
    	print '  Minus encode (print base.encode(-1)): ' 
    	try:
    		print base.encode(-1)
    	except ValueError as error:
    			print '   ' + error.__str__()

  11. #11
    SitePoint Zealot
    Join Date
    Dec 2010
    Posts
    187
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by whydna View Post
    Why don't those URL shorteners just generate a GUID?
    Because GUID is too long to be used for something in need of shortening.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •