2005/06/12

另外一個用了一點正規式寫出來的路徑修正函數

這個做法跟之前的比較,再於對要處理的字串先做一些處理,以減少之後在迴圈中判斷的複雜度。

function &路徑修正($路徑, $編碼 = false, $調整 = false) {
    $陣列 = explode('://', strtr($路徑, '\\', '/'), 2);
    //    取代 '/./', '/ /', '//' 這三類字串成為 '/'
    $比對 = '/\/((([\s]+)|([\s]*\.[\s]*))?\/)+/';
    $取代 = '/';
   
    if (2 == count($陣列)) {
        $前綴 = $陣列[0] . '://';
        $陣列 = explode('/', preg_replace($比對, $取代, $陣列[1]));
    } else {
        $前綴 = '';
        $陣列 = explode('/', preg_replace($比對, $取代, $陣列[0]));
    }
   
    $路徑 = array();
    foreach ($陣列 as $變數) {
        $測試 = trim($變數);
        if ('..' == $測試) {
            $測試 = end($路徑);
            if ('' == $測試 || '..' == $測試) {
                $路徑[] = '..';
            } else {
                array_pop($路徑);
            }
        } else if (false == $編碼) {
            $路徑[] = $變數;
        } else {
            $路徑[] = urlencode($變數);
        }
    }
   
    $路徑 = implode('/', $路徑);
    if ('' != $前綴) {
        $路徑 = $前綴 . $路徑;
    } else if ($調整 && (PHP_OS == 'WIN32' || PHP_OS == 'WINNT')){
        $路徑 = strtr($路徑, '/', '\\');
    }
    return $路徑;
}

2005/06/04

路徑修正函數

realpath有很多情況不能處哩,所以自己寫了一個路徑修正的程式去配合...
修正一個小錯誤...

function 路徑修正($路徑, $編碼 = false, $調整 = false) {
    $陣列 =    explode('://', strtr($路徑, '\\', '/'), 2);
    if (2 == count($陣列)) {
        $前綴 = $陣列[0];
        $陣列 = explode('/', $陣列[1]);
    } else {
        $前綴 = '';
        $陣列 = explode('/', $陣列[0]);
    }
   
    $路徑 = array();
    foreach ($陣列 as $變數) {
        $測試 = trim($變數);
        if ('..' == $測試) {
            if (0 == count($路徑) || '..' == end($路徑) || (1 == count($路徑) && '' == end($路徑))) {
                $路徑[] = '..';
            } else {
                while(1 < count($路徑) && '' == end($路徑)) {
                    array_pop($路徑);
                }
                array_pop($路徑);
            }
        } else if ('.' == $測試 || '' == $測試) {
            continue;
        } else {
            if (false == $編碼) {
                $路徑[] = $變數;
            } else {
                $路徑[] = urlencode($變數);
            }
        }
    }
    $路徑 = implode('/', $路徑);
    if ('' != $前綴) {
        $路徑 = "$前綴://$路徑";
    }
    if ((PHP_OS == 'WIN32' || PHP_OS == 'WINNT') && '' == $前綴 && true == $調整) {
        $路徑 = strtr($路徑, '/', '\\');
    }
    return $路徑;
}

2005/05/31

疊方塊的程式架構

前一陣子跑去玩了一下ASP.NET,從那邊學了一些東西拿到PHP上來用...
寫了一個小程式,運用事件的觀念,使用function把整個程式切開來,發現主程式已經能夠只表現流程,不含其他的程式碼...
底下是一個例子(include的那些函數跟物件我沒貼出來):
PS. 一開始也是寫的很混亂,這是慢慢的整理出來的結果

<?php
// 連結檔案
require_once dirname(__FILE__).'/link.php';
主程式();
function 主程式() {
    global $_頁面, $_解析, $_模組, $_訊息, $_錯誤, $_設定;
    初始();
    if (驗證()) {
        分配();
    }
    分頁();
    表列();
    解析();
}

function 初始() {
    global $_頁面, $_解析, $_模組, $_訊息, $_錯誤, $_設定;
    $模組 = array(
        '樣板' => &$_設定['樣板']['樣板檔案'],
        '資料庫' => &$_設定['資料庫']['連結'],
    );
    $_模組 = 模組::載入($模組);
}

function 驗證() {
    global $_頁面, $_解析, $_模組, $_訊息, $_錯誤, $_設定;
    $輸出 = true;
    $_頁面['表名陣列'] = array(
        'news_type' => '新聞分類',
        'history_type' => '事記分類',
        'product_type' => '產品分類'
    );
    $_頁面['表名'] = 檢查變數($_REQUEST['表名']);
    if (false == array_key_exists($_頁面['表名'], $_頁面['表名陣列'])) {
        $_頁面['表名'] = key($_頁面['表名陣列']);
        $輸出 = false;
    }
    return $輸出;
}

function 分配() {
    global $_頁面, $_解析, $_模組, $_訊息, $_錯誤, $_設定;
    switch (檢查變數($_POST['動作'])) {
        case '新增':
            新增();
            break;
        case '修改':
            修改();
            break;
    }
}

function 新增() {
    global $_頁面, $_解析, $_模組, $_訊息, $_錯誤, $_設定;
    $表名 = $_頁面['表名'];
    $資料庫 = &$_模組['資料庫'];
    $類名陣列 = explode("\n", 檢查變數($_POST['新增']['類名']));
    foreach($類名陣列 as $類名) {
        $類名 = trim($類名);
        if ('' != $類名) {
            $欄位 = array('類名' => $類名);
            $資料庫->autoExecute($表名, $欄位, DB_AUTOQUERY_INSERT);
        }
    }
}

function 修改() {
    global $_頁面, $_解析, $_模組, $_訊息, $_錯誤, $_設定;
    $表名 = $_頁面['表名'];
    檢查變數($_POST['主鍵'], array());
    foreach($_POST['主鍵'] as $主鍵 => $虛值) {
        $狀態 = 檢查變數($_POST['狀態'][$主鍵], 0, 'int');
        $類名 = trim(檢查變數($_POST['類名'][$主鍵], ''));
        if ('' != $類名) {
            $欄位 = array('狀態' => $狀態, '類名' => $類名);
            $_模組['資料庫']->autoExecute($表名, $欄位, DB_AUTOQUERY_UPDATE, "主鍵=$主鍵");
        }
    }
}

function 分頁() {
    global $_頁面, $_解析, $_模組, $_訊息, $_錯誤, $_設定;
    $資料庫 = &$_模組['資料庫'];
    $_設定['分頁']['totalItems'] = 資料庫::總數($資料庫, $資料庫->quoteIdentifier($_頁面['表名']));
    $_設定['分頁']['currentPage'] = 檢查變數($_REQUEST['pageID'], 0, 'int');
    $_設定['分頁']['extraVars']['表名'] = $_頁面['表名'];
    $_模組['分頁'] = 模組::分頁($_設定['分頁']);
}

function 表列() {
    global $_頁面, $_解析, $_模組, $_訊息, $_錯誤, $_設定;
    $資料庫 = &$_模組['資料庫'];
    $分頁 = &$_模組['分頁'];
   
    $命令 = sprintf('SELECT 主鍵, 狀態, 類名 FROM %s', $資料庫->quoteIdentifier($_頁面['表名']));
    $_解析['區塊'] = 資料庫::分頁($資料庫, $命令, $分頁->getOffsetByPageId());
    $_解析['全域'] = array(
        '網頁標題' => $_頁面['表名陣列'][$_頁面['表名']],
        '動作' => $_SERVER['PHP_SELF'],
        '分頁' => $分頁->links,
        '頁碼' => $分頁->getCurrentPageID(),
        '表名' => $_頁面['表名']
    );
}

function 解析() {
    global $_頁面, $_解析, $_模組, $_訊息, $_錯誤, $_設定;
    $樣板 = &$_模組['樣板'];
    $樣板->setCurrentBlock();
    解析區塊::表列($樣板, '區塊', '奇偶', '奇', '偶', $_解析['區塊']);
    $樣板->setVariable($_解析['全域']);
    $樣板->show();
}
?>

作縮圖用的一些程式

<?php
class 圖形 {
    // 顯示圖形
    public static function &顯示圖形(&$檔名, $寬度, $高度) {
        $參數 = getimagesize($檔名);
        if (false == $參數) {
            return '';
        }
        $參數 = self::比例參數($參數[0], $參數[1], $寬度, $高度);
        return sprintf('<img src=%s width=%s height=%s>',
            $檔名, $參數['寬度'], $參數['高度']
        );
    }

    // 傳回比例調整參數
    public static function &比例參數($來源寬度, $來源高度, $目的寬度, $目的高度) {
        $輸出 = array();
        $寬度比例 = $目的寬度 / $來源寬度;
        $高度比例 = $目的高度 / $來源高度;
        
        if (1 <= $寬度比例 && 1 <= $高度比例) {
            $輸出['寬度'] = $來源寬度;
            $輸出['高度'] = $來源高度;
        } else if ($寬度比例 > $高度比例) {
            $輸出['寬度'] = ceil($高度比例 * $來源寬度);
            $輸出['高度'] = $目的高度;
        } else {
            $輸出['寬度'] = $目的寬度;
            $輸出['高度'] = ceil($寬度比例 * $來源高度);
        }
        return $輸出;
    }

    // 調整圖檔型態字串
    public static function &圖檔型態(&$檔名, $型態 = null) {
        if (null === $型態) {
            $型態 = strtolower(pathinfo($檔名, PATHINFO_EXTENSION));
        } else {
            $型態 = strtolower($型態);
        }
        if ('jpg' == $型態) {
            $型態 = 'jpeg';
        }
        return $型態;
    }

    // 載入圖檔
    public static function &載入圖檔(&$檔名, $型態 = null) {
        $函數 = 'imagecreatefrom' . self::圖檔型態($檔名, $型態);
        return $函數($檔名);
    }

    // 寫入圖檔
    public static function 寫入圖檔(&$圖形, &$檔名, $型態 = null) {
        $函數 = 'image' . self::圖檔型態($檔名, $型態);
        $目錄 = dirname(realpath($檔名));
        if (false == is_dir($目錄)) {
            @mkdir($目錄, 0777, true);
        }
        return $函數($圖形, $檔名);
    }

    // 縮圖
    public static function 縮圖(&$來源檔名, &$目的檔名, $來源型態 = null, $目的型態 = null, $目的寬度 = 1, $目的高度 = 1) {
        $來源圖形 = self::載入圖檔($來源檔名, $來源型態);
        if ('' == $來源圖形) {
            return false;
        }
        $參數 = self::比例參數(imagesx($來源圖形), imagesy($來源圖形), $目的寬度, $目的高度);
        $目的圖形 = imagecreatetruecolor($參數['寬度'], $參數['高度']);
        imagecopyresampled($目的圖形, $來源圖形, 0, 0, 0, 0,
            $參數['寬度'], $參數['高度'], $來源寬度, $來源高度
        );
        $輸出 = self::寫入圖檔($目的圖形, $目的檔名, $目的型態);
        imagedestroy($目的圖形);
        imagedestroy($來源圖形);
        return $輸出;
    }
}
?>