Klassen (ik heb voor elk een apart bestand):
[code]<?php

class Card {
    const image_path = '/images/__SUIT_____SHORT__.gif';
    public static $tostring = 'image';
    public $id = -1;
    public $name = '';
    public $suit = '';
    public $value = -1;
    public $short = '';
    public $pth = -1;
    public function __construct($f_iCard) {
        $iCard = (int)$f_iCard%52;
        $iSuit = floor($iCard/13);
        $iName = $iCard%13;

        $arrSuits = array('clubs', 'diamonds', 'hearts', 'spades');
        $arrNames = array('ace', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'jack', 'queen', 'king');
        $arrShorts = array('a', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'j', 'q', 'k');
        $arrValues = array(11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10);
        $arrPTHValues = array(14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);

        $this->id = $iCard;
        $this->suit = $arrSuits[$iSuit];
        $this->name = $arrNames[$iName];
        $this->value = $arrValues[$iName];
        $this->short = $arrShorts[$iName];
        $this->pth = $arrPTHValues[$iName];
    }
    public function __tostring() {
        return call_user_func(array($this, self::$tostring));
        return $this->image();
    }
    public function small_image() {
        return '<img src="'.str_replace('__SUIT_____SHORT__', $this->suit, self::image_path).'" /> '.strtoupper($this->short);
    }
    public function image() {
        $r = array(
            '__SHORT__'    => $this->short,
            '__NAME__'    => $this->name,
            '__SUIT__'    => $this->suit,
            '__CARD__'    => $this->id,
        );
        return '<img title="'.$this->id.'" src="'.strtr(self::image_path, $r).'" />';
    }
    public function html() {
        return strtoupper($this->short) . ' of ' . $this->suit;
    }
    public static function random() {
        return new Card(rand(0,51));
    }
}

class Deck {
    public $iNextCard = 0; # protected
    public $cards = array(); # protected
    public function __construct($f_bFill = true) {
        if ( $f_bFill ) {
            foreach ( range(0, 51) AS $iCard ) {
                array_push($this->cards, new Card($iCard));
            }
        }
    }
    public function next() {
        if ( !isset($this->cards[$this->iNextCard]) ) {
            return null;
        }
        return $this->cards[$this->iNextCard++];
    }
    public function size() {
        return (count($this->cards)-$this->iNextCard);
    }
    public function add_deck(Deck $objDeck) {
        $this->cards = array_merge($this->cards, $objDeck->cards);
        return $this;
    }
    public function add_card(Card $objCard) {
        array_push($this->cards, $objCard);
        return $this;
    }
    public function shuffle() {
        return shuffle($this->cards);
    }
    public function replenish() {
        $this->iNextCard = 0;
        $this->shuffle();
    }
    public function __tostring() {
        return implode("\n", $this->cards);
    }
}

class pokertexasholdem {
    public $cards = array();
    public $values = array();
    public $num_values = array();
    public $suits = array();
    public $num_suits = array();
    public function __construct($f_arrCards) {
        $this->cards = $f_arrCards;
        $tmp = array();
        foreach ( $f_arrCards AS $objCard ) {
            $tmp[] = array(
                'value'    => (int)$objCard->pth,
                'suit'    => (string)$objCard->suit,
            );
        }
        $rev2d = self::flip_2d_array($tmp);

        $this->values = $rev2d['value'];
        arsort($this->values);
        $this->num_values = array_count_values($this->values);

        $this->suits = $rev2d['suit'];
        asort($this->suits);
        $this->num_suits = array_count_values($this->suits);
        arsort($this->num_suits);
    }

    public static function readable_hand($f_fHand) {
        $arrCardsText = array(2 => 'Twos', 'Threes', 'Fours', 'Fives', 'Sixes', 'Sevens', 'Eights', 'Nines', 'Tens', 'Jacks', 'Queens', 'Kings', 'Aces');
        $arrCardsShort = array(2 => '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A');
        $x = explode('.', (string)$f_fHand, 2);
        $szExtra = isset($x[1]) ? $x[1] : '';
        $szHand = '';
        switch ( (int)$x[0] )
        {
            case 9:
                $szHand = 'Royal Flush of '.ucfirst(strtolower($szExtra)).'';
            break;

            case 8:
                $szHand = 'Straight Flush of '.ucfirst(strtolower(substr($szExtra, 2))).' - '.$arrCardsText[(int)substr($szExtra, 0, 2)].' high';
            break;

            case 7:
                $szHand = 'Four Of A Kind - '.$arrCardsText[(int)substr($szExtra, 0, 2)].'';
            break;

            case 6:
                $szHand = 'Full House - '.$arrCardsText[(int)substr($szExtra, 0, 2)].' over '.$arrCardsText[(int)substr($szExtra, 2, 2)].'';
            break;

            case 5:
                $szHand = 'Flush of '.ucfirst(strtolower(substr($szExtra, 10))).' - '.$arrCardsText[(int)substr($szExtra, 0, 2)].' high';
            break;

            case 4:
                $szHand = 'Straight - '.$arrCardsText[(int)substr($szExtra, 0, 2)].' high';
            break;

            case 3:
                $szHand = 'Three Of A Kind - '.$arrCardsText[(int)substr($szExtra, 0, 2)].'';
            break;

            case 2:
                $szHand = 'Two Pairs - '.$arrCardsText[(int)substr($szExtra, 0, 2)].' and '.$arrCardsText[(int)substr($szExtra, 2, 2)].'';
            break;

            case 1:
                $szHand = 'One Pair of '.$arrCardsText[(int)substr($szExtra, 0, 2)].'';
            break;

            case 0:
            default:
                $arrKickers = array($arrCardsShort[(int)substr($szExtra, 0, 2)]);
                if ( 0 < ($c=(int)substr($szExtra, 2, 2)) ) {
                    $arrKickers[] = $arrCardsShort[$c];
                }
                if ( 0 < ($c=(int)substr($szExtra, 4, 2)) ) {
                    $arrKickers[] = $arrCardsShort[$c];
                }
                if ( 0 < ($c=(int)substr($szExtra, 6, 2)) ) {
                    $arrKickers[] = $arrCardsShort[$c];
                }
                if ( 0 < ($c=(int)substr($szExtra, 8, 2)) ) {
                    $arrKickers[] = $arrCardsShort[$c];
                }
                $szHand = 'High Cards '.implode(', ', $arrKickers).'';
            break;
        }
        return $szHand;
    }

    # 9
    public function royal_flush() {
        $szStraigtFlush = $this->straight_flush();
        if ( '14' === substr($szStraigtFlush, 0, 2) ) {
            return substr($szStraigtFlush, 2);
        }
        return null;
    }
    # 8
    public function straight_flush() {
        if ( null === ($szSuit=$this->flush(true)) ) {
            return null;
        }
        $arrCards = array();
        foreach ( $this->values AS $iCard => $iValue ) {
            if ( $szSuit == $this->suits[$iCard] ) {
                $arrCards[] = $iValue;
            }
        }
        if ( null !== ($szHiCard=$this->straight($arrCards)) ) {
            return $szHiCard.$szSuit;
        }
        return null;
    }
    # 7
    public function four_of_a_kind() {
        foreach ( $this->num_values AS $iValue => $iAmount ) {
            if ( 4 <= $iAmount ) {
                $szExtra = self::padleft($iValue);
                foreach ( $this->values AS $v ) {
                    if ( $v != $iValue ) {
                        $szExtra .= self::padleft($v);
                        return $szExtra;
                    }
                }
            }
        }
        return null;
    }
    # 6
    public function full_house() {
        if ( null !== ($szPair=$this->one_pair()) && null !== ($szThreeOfAKind=$this->three_of_a_kind()) ) {
            return substr($szThreeOfAKind, 0, 2).substr($szPair, 0, 2);
        }
        return null;
    }
    # 5
    public function flush($f_bSimple = false) {
        if ( 5 <= reset($this->num_suits) ) {
            $szSuit = key($this->num_suits);
            if ( $f_bSimple ) {
                return $szSuit;
            }
            $szExtra = '';
            foreach ( $this->values AS $iCard => $iValue ) {
                if ( $szSuit == $this->suits[$iCard] && 10 > strlen($szExtra) ) {
                    $szExtra .= self::padleft($iValue);
                }
                if ( 10 <= strlen($szExtra) ) {
                    break;
                }
            }
            return $szExtra.$szSuit;
        }
        return null;
    }
    # 4
    public function straight($f_arrValues = null) {
        $arrValues = is_array($f_arrValues) ? $f_arrValues : array_keys($this->num_values);
        if ( 5 > count($arrValues) ) {
            // Not even 5 different cards
            return null;
        }
        for ( $i=0; $i<=count($arrValues)-5; $i++ ) {
            // loop next 5 cards
            $iHiCard = $iPrevValue = $arrValues[$i];
            $bOk = true;
            for ( $j=$i+1; $j<$i+5; $j++ ) {
                if ( $arrValues[$j] != $iPrevValue-1 ) {
                    $bOk = false;
                    break;
                }
                $iPrevValue = $arrValues[$j];
            }
            if ( $bOk ) {
                return self::padleft($iHiCard);
            }
        }
        # ace to 5
        if ( in_array(14, $arrValues) && in_array(2, $arrValues) && in_array(3, $arrValues) && in_array(4, $arrValues) && in_array(5, $arrValues) ) {
            return '05';
        }
        return null;
    }
    # 3
    public function three_of_a_kind() {
        foreach ( $this->num_values AS $iValue => $iAmount ) {
            if ( 3 == $iAmount ) {
                $szExtras = self::padleft($iValue);
                foreach ( $this->values AS $v ) {
                    if ( $iValue != $v && 6 > strlen($szExtras) ) {
                        $szExtras .= self::padleft($v);
                    }
                    if ( 6 <= strlen($szExtras) ) {
                        break;
                    }
                }
                return $szExtras;
            }
        }
        return null;
    }
    # 2
    public function two_pair() {
        $szExtras = '';
        $iVal1 = $iVal2 = 0;
        foreach ( $this->num_values AS $iValue => $iAmount ) {
            if ( 2 == $iAmount && 4 > strlen($szExtras) ) {
                $szExtras .= self::padleft($iValue);
            }
        }
        if ( 4 == strlen($szExtras) ) {
            foreach ( $this->values AS $v ) {
                if ( $iVal1 != $v && $iVal2 != $v ) {
                    $szExtras .= self::padleft($v);
                    break;
                }
            }
            return $szExtras;
        }
        return null;
    }
    # 1
    public function one_pair() {
        foreach ( $this->num_values AS $iValue => $iAmount ) {
            if ( 2 == $iAmount ) {
                $szExtras = self::padleft($iValue);
                foreach ( $this->values AS $v ) {
                    if ( $iValue != $v && 8 > strlen($szExtras) ) {
                        $szExtras .= self::padleft($v);
                    }
                    if ( 8 <= strlen($szExtras) ) {
                        break;
                    }
                }
                return $szExtras;
                break;
            }
        }
        return null;
    }

    public function _score() {
        $arrCheckingOrder = array(
            'royal_flush',
            'straight_flush',
            'four_of_a_kind',
            'full_house',
            'flush',
            'straight',
            'three_of_a_kind',
            'two_pair',
            'one_pair',
        );
        $iScore = 0;
        foreach ( $arrCheckingOrder AS $iRevHandValue => $szCall ) {
            if ( null !== ($szExtra=call_user_func(array($this, $szCall))) ) {
                $iScore = 9-$iRevHandValue;
                break;
            }
        }
        if ( 0 >= $iScore ) {
            // high card
            $iScore = 0;
            $szExtra = '';
            foreach ( $this->values AS $v ) {
                if ( 10 > strlen($szExtra) ) {
                    $szExtra .= self::padleft($v);
                }
                if ( 10 <= strlen($szExtra) ) {
                    break;
                }
            }
        }
        return ($iScore.'.'.(string)$szExtra);
    }
    public static function padleft($s) {
        return str_pad((string)$s, 2, '0', STR_PAD_LEFT);
    }
    public static function score($c) {
        $o = new self($c);
        return $o->_score();
    }
    public static function flip_2d_array($a) {
        $r = array();
        foreach ( $a AS $k1 => $v1 ) {
            foreach ( $v1 AS $k2 => $v2 ) {
                $r[$k2][$k1] = $v2;
            }
        }
        return $r;
    }
}

?>

Voorbeeld:
<?php

require_once('inc.cls.card.php');
require_once('inc.cls.deck.php');
require_once('inc.cls.pokertexasholdem.php');

Card::$tostring = 'small_image';

$objDeck = new Deck();
$objDeck->shuffle();

$iPlayers = 12;
$iMinScore = 4.0;

$arrPublic = $arrPlayers = array();
for ( $i=0; $i<$iPlayers; $i++ ) {
    $arrPlayers[$i] = array();
    array_push($arrPlayers[$i], $objDeck->next());
    array_push($arrPlayers[$i], $objDeck->next());
}
while ( 5 > count($arrPublic) ) {
    array_push($arrPublic, $objDeck->next());
}

$fUtcStart = microtime(true);

/* test *
$arrPublic = array(
    new Card(8),
    new Card(0),
    new Card(3),
    new Card(7),
    new Card(6),
);
$arrPlayers[0] = array(
    new Card(5),
    new Card(4),
);
/* test */

?>
<html>

<head>
<style type="text/css">
body, table {
    background-color: #444;
    font-family        : verdana, arial;
    font-size        : 10px;
    color            : white;
}
</style>
</head>

<body>
<?php

$bNothingWorthy = true;
$iMaxHand = 0;
$arrHands = array();
echo '<table border="0" cellpadding="2" cellspacing="1">';
foreach ( $arrPlayers AS $k => $arrPlayer ) {
    echo '<tr>';
    if ( 0 == $k ) {
        echo '<td rowspan="'.count($arrPlayers).'">'.implode(', ', $arrPublic).'</td>';
        echo '<td rowspan="'.count($arrPlayers).'">&nbsp;+&nbsp;</td>';
    }
    $fHand = pokertexasholdem::score(array_merge($arrPublic, $arrPlayer));
    $arrHands[] = $fHand;
    if ( (float)$fHand > (float)$iMaxHand ) {
        $iMaxHand = $fHand;
    }
    if ( $iMinScore <= (float)$fHand ) {
        $bNothingWorthy = false;
        $szHand = '<b style="color:red;">'.$fHand.'</b>';
    }
    else {
        $szHand = $fHand;
    }
    echo '<td>'.implode(', ', $arrPlayer).'</td>';
    echo '<td>&nbsp;=&nbsp;</td>';
    echo '<td>'.$szHand.'</td>';
    echo '<td>&nbsp;=&nbsp;</td>';
    echo '<td>'.pokertexasholdem::readable_hand($fHand).'</td></tr>';
}
echo '<tr><td colspan="7" align="center">Winner: '.pokertexasholdem::readable_hand($m=max($arrHands)).' ('.$m.')</td></tr>';
echo '</table>';

if ( $bNothingWorthy ) {
    echo '<meta http-equiv="refresh" content="0" />';
}

echo '<p>'.number_format(($fTime=microtime(true)-$fUtcStart), 4).'</p>';

?>
</body>

<title><?php echo $iMaxHand; ?></title>

</html>[/code]