<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-31  評論-257  文章-0  trackbacks-0
     
    發(fā)現(xiàn)一篇好文,介紹AS3中常見的位運算技巧的。小弟勉強翻譯一下,有錯誤還請指正。原文在這里

    在AS3中位操作是非常快的,這里列出一些可以加快某些計算速度的代碼片段集合。我不會解釋什么是位運算符,也不會解釋怎么使用他們,只能告訴大家如果想清楚其中的原理這里有一篇極好的文章在gamedev.net上叫做 ‘Bitwise Operation in C' .

    如果你知道任何下邊沒有列出來的不錯的技巧,請留下個評論或者給我發(fā)個郵件。所有這些都是基于AS3的

    [b]左位移幾就相當(dāng)于乘以2的幾次方[/b]( Left bit shifting to multiply by any power of two )

    大約快了300%
    [code]
    x = x * 2;
    x = x * 64;
    //相當(dāng)于:
    x = x << 1;
    x = x << 6;
    [/code]
    [b]右位移幾就相當(dāng)于除以2的幾次方[/b](Right bit shifting to divide by any power of two)
    大約快了350%
    [code]
    x = x / 2;
    x = x / 64;
    //相當(dāng)于:
    x = x >> 1;
    x = x >> 6;
    [/code]
    [b]Number 到 integer(整數(shù))轉(zhuǎn)換[/b]

    在AS3中使用int(x)快了10% 。盡管如此位操作版本在AS2中工作的更好
    [code]
    x = int(1.232)
    //相當(dāng)于:
    x = 1.232 >> 0;
    [/code]
    [b]提取顏色組成成分[/b]

    不完全是個技巧,是正常的方法 (Not really a trick, but the regular way of extracting values using bit masking and shifting.)
    [code]
    //24bit
    var color:uint = 0x336699;
    var r:uint = color >> 16;
    var g:uint = color >> 8 & 0xFF;
    var b:uint = color & 0xFF;
    //32bit
    var color:uint = 0xff336699;
    var a:uint = color >>> 24;
    var r:uint = color >>> 16 & 0xFF;
    var g:uint = color >>> 8 & 0xFF;
    var b:uint = color & 0xFF;
    [/code]
    [b]合并顏色組成成分[/b]

    替換值到正確位置并組合他們 (‘Shift up’ the values into the correct position and combine them.)
    [code]
    //24bit
    var r:uint = 0x33;
    var g:uint = 0x66;
    var b:uint = 0x99;
    var color:uint = r << 16 | g << 8 | b;
    //32bit
    var a:uint = 0xff;
    var r:uint = 0x33;
    var g:uint = 0x66;
    var b:uint = 0x99;
    var color:uint = a << 24 | r << 16 | g << 8 | b;
    [/code]
    [b]使用異或運算交換整數(shù)而不需要用臨時變量[/b]

    很可愛的技巧, 在本頁頂端的鏈接里有詳細(xì)的解釋 ,這里快了 20%
    [code]
    var t:int = a;
    a = b;
    b = t;
    //相當(dāng)于:
    a ^= b;
    b ^= a;
    a ^= b;
    [/code]
    [b]自增/自減(Increment/decrement)[b]

    這個比以前的慢不少,但卻是個模糊你代碼的好方法;-)
    [code]
    i = -~i; // i++
    i = ~-i; // i--
    [/code]
    [b]取反[/b](Sign flipping using NOT or XOR)

    另人奇怪的是這個居然快了300%!
    [code]
    i = -i;
    //相當(dāng)于:
    i = ~i + 1;
    //或者
    i = (i ^ -1) + 1;
    [/code]
    [b]使用bitwise AND快速取模[/b] (Fast modulo operation using bitwise AND)

    如果除數(shù)是2的次方,取模操作可以這樣做:

    模數(shù)= 分子 & (除數(shù) - 1);

    這里大約快了600%
    [code]
    x = 131 % 4;
    //相當(dāng)于:
    x = 131 & (4 - 1);
    [/code]
    [b]檢查是否為偶數(shù)[/b](Check if an integer is even/uneven using bitwise AND)

    這里快了 600%
    [code]
    isEven = (i % 2) == 0;
    //相當(dāng)于:
    isEven = (i & 1) == 0;
    [/code]
    [b]絕對值[/b]

    忘記 Math.abs()吧 (Forget Math.abs() for time critical code.)

    version 1 比 Math.abs() 快了2500% ,version 2 居然比 version 1 又快了20% !
    [code]
    //version 1
    i = x < 0 ? -x : x;
    //version 2
    i = (x ^ (x >> 31)) - (x >> 31);
    [/code]


    posted @ 2008-07-29 14:14 姜大叔 閱讀(311) | 評論 (0)編輯 收藏
          好久沒寫文章了,上一個多月,很多很多煩人的事情,我也不想多說了,導(dǎo)致了沒時間寫文章了,不過今后的時間將會多點,所以在這段時間里打算多寫點技術(shù)文章來填充一下Blog,主要是Flash與Java方面吧。
          今天做了一個小東西,一個會轉(zhuǎn)動的3D盒子的效果,用于切換不同的內(nèi)容面板,是一個不錯的Flex效果,該東西是用了DistortionEffects做的,首先感謝Dreamer介紹了DistortionEffects這個東東,我也是在他Blog里看到,之后用來做點東西試試的。以下是Dreamer里的一編文章:[url=http://www.zhuoqun.net/html/y2007/492.html]DistortionEffects[/url]



          其實這個很簡單,只是使用了DistortionEffects里面的CubeRotate效果,很炫的效果,致至該效果的實現(xiàn),還有待看看它的源碼進(jìn)行研究研究!

    以下放出我的該小Flex的源碼:
    [mDown=attachments/month_0712/j20071225181513.rar]點擊下載此文件[/mDown]
    posted @ 2008-07-29 14:13 姜大叔 閱讀(6538) | 評論 (48)編輯 收藏
    本篇接著上一篇文章,上篇文章中,大家都看到最終效果了,這個例子很簡單,我就粗略的講解一下代碼吧
    整個Flex程序,就兩個Panel面板,將控件都排放好到Panel里面,之后定好相應(yīng)的屬性,我主要解析一下下面的代碼:
     1 <mx:Script>
     2         <![CDATA[
     3         //導(dǎo)入需要用到的類
     4         import mx.utils.Base64Encoder;
     5         import mx.collections.ArrayCollection;
     6         import mx.controls.Alert;
     7         import com.adobe.images.PNGEncoder;
     8        
     9         //這里定義一個ArrayCollection 這就是PieChart控件所需要的dataProvider,并賦好初值
    10         [Bindable]
    11         private var mydata:ArrayCollection = new ArrayCollection([
    12             {name: "非常滿意",num: 1},
    13             {name: "滿意",num: 1},
    14             {name: "普通",num: 1},
    15             {name: "不滿意",num: 1},
    16             {name: "非常不滿意",num: 1}
    17         ]);
    18        
    19         //方法為PieChart控件自動調(diào)用的,是用于當(dāng)圖表要顯示Label時,將會調(diào)用該方法,并傳上相應(yīng)的參數(shù),這樣,你就可以在該方法里自已處理好要顯示的數(shù)據(jù),再返回給Chart顯示
    20         private function showLabel(data:Object, field:String, index:Number, percentValue:Number):String{
    21             return data.name + ":" + data.num + "\n" + Math.round(percentValue) + "%";
    22         }
    23        
    24         //該方法是當(dāng)點擊“確定”按鈕時調(diào)用的,用于改變圖表數(shù)據(jù)的ArrayCollection里的數(shù)據(jù),再更新圖表顯示
    25         private function changeData(ent:Event):void{
    26             //定一個臨時的集合用于放置數(shù)據(jù)
    27             var temp:ArrayCollection = new ArrayCollection();
    28             //判斷用戶所填的數(shù)據(jù)是否為空,如果為空的就不要加進(jìn)集合里了,免得圖表出現(xiàn)一些無謂的Label,下同
    29             if(resu0.text != ""){
    30                 temp.addItem({name: "非常滿意",num: resu0.text});
    31             }
    32             if(resu1.text != ""){
    33                 temp.addItem({name: "滿意",num: resu1.text});
    34             }
    35             if(resu2.text != ""){
    36                 temp.addItem({name: "普通",num: resu2.text});
    37             }
    38             if(resu3.text != ""){
    39                 temp.addItem({name: "不滿意",num: resu3.text});
    40             }
    41             if(resu4.text != ""){
    42                 temp.addItem({name: "非常不滿意",num: resu4.text});
    43             }
    44             panel1.title = subjectTitle.text;
    45             /*
    46             mydata[0].num = resu0.text;
    47             mydata[1].num = resu1.text;
    48             mydata[2].num = resu2.text;
    49             mydata[3].num = resu3.text;
    50             mydata[4].num = resu4.text;
    51             */
    52             pc.dataProvider = temp;
    53         }
    54        
    55         //這里是截圖的方法函數(shù),參照于國外某高手地Flex截圖方面的代碼
    56         private function catchPic(ent:Event):void{
    57             //根據(jù)要截圖的Panel的大小建立一個放置位圖數(shù)據(jù)的BitmapData對象
    58             var bitmapData:BitmapData = new BitmapData(panel1.width,panel1.height,true,0xffffff);
    59             //用現(xiàn)時panel1對象的位圖信息填充到bitmapData對象中
    60             //由于每一個DisplayObject對象都有自已的用于顯示的位圖色彩信息,
    61             //所以很多繼承了DisplayObject的類都可以填充到bitmapData對象中處理,如模糊處理等
    62             bitmapData.draw(panel1);
    63             //用PNGEncoder類對位圖信息進(jìn)行壓縮轉(zhuǎn)換處理才得以輸出PNG圖片格式數(shù)據(jù)
    64             var bytes:ByteArray = PNGEncoder.encode(bitmapData);
    65             //再將數(shù)據(jù)進(jìn)行編碼,用于在JavaScript中向瀏覽器傳播
    66             //最后調(diào)用JavaScript來打開新窗口來顯示圖借數(shù)據(jù)
    67             var b64encoder:Base64Encoder = new Base64Encoder();
    68             b64encoder.encodeBytes(bytes);
    69             ExternalInterface.call("showPic",b64encoder.flush(),panel1.width+25,panel1.height+25);
    70         }
    71         ]]>
    72 </mx:Script>


    JavaScript方面要寫上以下函數(shù):

    1 function showPic(img,width,height){
    2     window.open("data:image/png;base64," + img,"","width="+width+",height="+height+",resizable=1");
    3 }



    以上有幾點應(yīng)該要注意:
    注意PieChart的dataProvider的寫法,也就是ArrayCollection的寫法,這與很多控件的dataProvider的都一樣,比如DataGrid控件。
    注意,PNGEncoder類不是Flex原本自帶的,是要另外自已下載的擴(kuò)展包,在com.adobe.images里面,是Adobe發(fā)布的核心擴(kuò)展類庫,更多的類庫,大家可以在網(wǎng)上找找。

    以下放出完整的源代碼:[down=attachments/month_0710/92007102323188.rar]點擊下載此文件[/down]


    posted @ 2008-07-29 14:10 姜大叔 閱讀(2773) | 評論 (4)編輯 收藏
          應(yīng)朋友要求,做一個數(shù)據(jù)圖表的東西,主要是用于將數(shù)據(jù)以圖表的方式表示,以不至于用Excel看一大表格,里面密密麻麻的數(shù)字,所以,第一時間想到用Flex Chart玩玩,由于原本已有點Flex基礎(chǔ),So,F(xiàn)lex Chart也不是太難,而且效果滿意漂亮,也就當(dāng)作開拓該方面技術(shù)的練手之作吧,程序很簡單,就在一邊輸入數(shù)據(jù),另一邊則顯示該數(shù)據(jù)所表示的餅圖圖形,后來并加上了“生成圖片”按鈕,該功能是參照外國某位牛人所做的,不過就是該功能只支持FireFox。



    [url=jiang/catch_chart/chart.html]可以去這里看看效果[/url]

    待會我整理好源代碼,再放出源代碼,并解析一下該程序。


    posted @ 2008-07-29 14:08 姜大叔 閱讀(2301) | 評論 (0)編輯 收藏
        這幾天無聊著,打開163郵箱,看到右上角的天氣信息,突然心血來潮,自已也做個天氣信息的小模塊放在Blog上,就是左邊側(cè)欄的那個,其實之前都做過,只不過是用Java來解析,F(xiàn)lex來顯示,而已之前的那個是解析www.weathercn.com的信息的,但現(xiàn)在該站的天氣頁面改版了,所以不得不重新做,既然如此,就拿163的來做吧。原理都是一樣,用PHP讀取163的天氣信息網(wǎng)頁,再用正則表達(dá)式解析網(wǎng)頁的內(nèi)容,提取有用的天氣信息,組織好成XML格式,之后Flex用WebService來讀取該PHP,得到XML數(shù)據(jù),再相應(yīng)的顯示。
        其實這并不難,打開的我163郵箱,查看它的網(wǎng)頁源碼,經(jīng)過一番的查找分析,找到它獲取天氣信息的網(wǎng)頁:http://mimg.163.com/tianqi/city/59287.html  呵呵,還是Html的哦,網(wǎng)易的將動態(tài)的天氣生成靜態(tài)的頁面,我們訪問起來,也不太占服務(wù)器資源吧,因為天氣也是經(jīng)常訪問的。看看源代碼,就幾行Html代碼,正合我的需求,免得我的PHP分析大量的代碼占點資源。不過有點要注意,網(wǎng)易把每個城市的代號生成一個頁面,即是一個城市,一個天氣頁面,上面那個URL是廣州的,就是說 59287 就是廣州的城市代碼,在PHP里訪問時,要跟據(jù)用戶選的是哪個城市,相對應(yīng)的修改那個號碼就行了,如:
    $url = "http://mimg.163.com/tianqi/city/".$_GET['city'].".html";
    這樣,你訪問PHP時,要傳一個城市代碼參數(shù),至于網(wǎng)易定義的城市代碼,我這里就不列出來了,太多太長了,也找了我不少時間。我放在Flex的源碼里,可以下載我的源碼看看。
    以下是PHP頁面的代碼:
     1 <?php
     2     include("class.Chinese.php");        #導(dǎo)入字符集轉(zhuǎn)換的類
     3     $codeTableDir = "./config/";        #指定字符碼表的路徑
     4 
     5     $url = "http://mimg.163.com/tianqi/city/".$_GET['city'].".html";        #獲取城市代碼,組成完整的URL
     6    
     7     $fh = fopen($url,'r');                #讀取該URL獲取內(nèi)容
     8     while(!feof($fh)){
     9         $content .= fread($fh,128);        #讀取全部內(nèi)容
    10     }
    11     $content = new Chinese("GB2312","UTF8",$content,$codeTableDir);            #轉(zhuǎn)換字符碼,GB轉(zhuǎn)UTF8
    12     $content = $content->ConvertIT();                                        #轉(zhuǎn)換
    13     eregi('(<span class="wetCityName">)([^/]*)(</span>)',$content,$arr);    #找出表示城市的內(nèi)容
    14     $city = $arr[2];
    15    
    16     eregi('(<span class="wetDate">)(.*)(</span></div>)',$content,$arr);        #找出表示日期的內(nèi)容
    17     $date = $arr[2];
    18    
    19     $wea = split('txtAlgCen fRig handle',$content);                            #分開今天與明天
    20    
    21     eregi('(<div class="wetSts">)([^<]*)(</div>)',$wea[0],$arr);            #找出表示今日天氣的內(nèi)容
    22     $info1 = $arr[2];
    23     eregi('(<div class="wetSts">)([^<]*)(</div>)',$wea[1],$arr);            #找出表示明日天氣的內(nèi)容   下同
    24     $info2 = $arr[2];
    25    
    26     eregi('(</b>)([^<]*)(</div>)',$wea[0],$arr);
    27     $temp1 = $arr[2];
    28     eregi('(</b>)([^<]*)(</div>)',$wea[1],$arr);
    29     $temp2 = $arr[2];
    30    
    31     eregi('(class="wetDico )(.*)("></div>)',$wea[0],$arr);
    32     $pic1 = $arr[2];
    33     eregi('(class="wetDico )(.*)("></div>)',$wea[1],$arr);
    34     $pic2 = $arr[2];
    35    
    36     echo "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
    37     echo "\n";
    38 ?>
    39 <weather>
    40     <city><?= $city ?></city>
    41     <date><?= $date ?></date>
    42     <today>
    43         <wea><?= $info1 ?></wea>
    44         <temp><?= $temp1 ?></temp>
    45         <pic><?= $pic1 ?></pic>
    46     </today>
    47     <tomorrow>
    48         <wea><?= $info2 ?></wea>
    49         <temp><?= $temp2 ?></temp>
    50         <pic><?= $pic2 ?></pic>
    51     </tomorrow>
    52 </weather>

    以上有幾點要注意:
        1。由于網(wǎng)易里的網(wǎng)頁是用GB2312編碼的,而Flex里接收的XML要UTF-8編碼才會正確讀出,所以要將獲取的網(wǎng)易里的數(shù)據(jù)進(jìn)行轉(zhuǎn)碼,這問題剛開始時,老是亂碼,搞到心煩,后來發(fā)現(xiàn)網(wǎng)易的Html的頭信息里 發(fā)現(xiàn)是GB2312的編碼,郁悶了半天,之后上網(wǎng)找了個中文轉(zhuǎn)碼的類,下載來直接套用。
        2。獲取回來的天氣信息的Html是分今天與明天的天氣信息,而里面的格式也是一樣的,所以,用正則查找時,只找到最先的那個,所以要先找個今天與明天的分界點,將其分離開來再各自解析里面的內(nèi)容,得出今天的天氣與明天的天氣。
        3。寫輸出XML時,格式要正確,不然Flex里讀取會有麻煩,還有,encoding一定要是UTF-8,還要將該PHP文件保存成UTF-8格式,我用DW寫該PHP時,因為我的DW新建文件時,默認(rèn)是ISO8859-1的,所以要將其文檔編碼格式改為UTF-8來保存。

    PHP完工之后,來到Flex這邊,畫好界面,添加代碼如下:
    先加一個HttpService標(biāo)簽 :
    <mx:HTTPService id="hs" showBusyCursor="true" method="GET" result="{hsResult(event);}" fault="{hsFault(event);}" />
    (事件響應(yīng)方法我就不在這里貼出來了,可下載源碼看)
    當(dāng)下拉選框選中城市之后,判斷用戶選中的是哪個城市,再對照該城市的代號,組合成URL
    hs.url = "http://www.jiangzone.com.cn/jiang/weather/weather.php?city=" + cityvalues[i];
    hs.send();
    結(jié)果返回時,再相應(yīng)的賦值:
    lblCity.text = event.result.weather.city;
    lblDate.text = event.result.weather.date;
    lblWea.text = event.result.weather.today.wea;
    weather對應(yīng)XML里的<weather>根標(biāo)簽,city對應(yīng)XML里的<city>標(biāo)簽。

    OK,修改一下,大功告成!
    以下是源碼:

    [down=attachments/month_0709/t2007916122822.rar]點擊下載此文件[/down]


    posted @ 2008-07-29 14:07 姜大叔 閱讀(1221) | 評論 (1)編輯 收藏
    adobe的一些as3類庫提供給google code(http://actionscript3libraries.riaforge.org/)可以隨意下載...
    其中的as3corelib里面包含image的png和jpg類和json(序列化數(shù)據(jù))類包.

    同時amfphp1.9beta的發(fā)布可以讓你用remoting來傳遞amf3格式的數(shù)據(jù).

    那么有了這兩個條件我們就可以用他們來直接生成png和jpg格式的圖片...

    使用方法也是比較簡單,使用前面我提供的方法可以很方便的實現(xiàn)...


    as3corelib里面的png和jpg類

    [down=attachments/month_0709/r2007917165754.rar]點擊下載此文件[/down]

    as代碼:
    //------------------------------------------------------------------------------------
    //在舞臺上放一個mc名字為a,mc包含一些隨意的圖形
    import flash.net.*;
    import flash.display.*;
    var hostName:String = "http://localhost/amfphp/";
    var gatewayUrl:String = hostName+"gateway.php";
    ////////////////////////////
    var bpd:BitmapData = new BitmapData(a.width, a.height);
    bpd.draw(a);
    //var jpegEnc:JPEGEncoder = new JPEGEncoder(80);
    //var dat:ByteArray = jpegEnc.encode(bpd);
    var dat:ByteArray = PNGEncoder.encode(bpd);
    //
    var nc:NetConnection = new NetConnection();
    //nc.objectEncoding = 0;
    nc.connect(gatewayUrl);
    //
    nc.call("SavePic.save",new Responder(onResult,onFault),dat);
    //nc.call("SavePic.test",new Responder(onResult,onFault),"h..roading");
    /////////////////////////////
    function onResult(re:Object)
    {
     trace(re);
    }
    function onFault(re:Object)
    {
     trace(re);
     for(var i in re)
     trace(i+"=>"+re[i]);
    }
    //----------------------------------------------------------------------------------------------


    php代碼:
     1 //-----------------------------------------------------------------------------------------------
     2 <?php
     3 
     4 class SavePic
     5 {
     6 
     7  function Tuya()
     8  {
     9   $this->methodTable = array(
    10    "save" => array(
    11     "access" => "remote"
    12    ),
    13    "test" => array(
    14     "access" => "remote"
    15    )
    16   );
    17  }
    18  function test($str)
    19  {
    20   return $str;
    21 
    22 
    23  }
    24 
    25 
    26  function save($data)
    27  {
    28   $name = time().'.jpg'//png
    29  
    30   $im = fopen($name,'a');
    31 
    32   fwrite($im,$data);
    33  
    34   fclose($im);
    35 
    36   return $name;
    37  }
    38 }
    39 ?>
    40 
    41 

    posted @ 2008-07-29 14:05 姜大叔 閱讀(246) | 評論 (0)編輯 收藏
          在關(guān)系數(shù)據(jù)庫應(yīng)用中,都離不開表與表的關(guān)聯(lián),表與表之間建立了關(guān)聯(lián)關(guān)系后就可以提供很多方便的操作了,比如我要查詢一個學(xué)生的信息,如果不建立學(xué)生與班級的關(guān)系的話,那么,只可以顯示出學(xué)生的基本信息,而學(xué)生是屬于某一個班級的,我現(xiàn)在想知道這個學(xué)生的信息與該學(xué)生所在的班級的信息,甚至是該學(xué)生的任課老師等信息,建立了學(xué)生表,與班級表,老師表之間的關(guān)系就方便好多了,用一個學(xué)生ID就可以查找出所有相關(guān)聯(lián)的數(shù)據(jù)。

    在FleaPHP中,支持以下四種關(guān)聯(lián)關(guān)系:
             
          * HAS_ONE
          * HAS_MANY
          * MANY_TO_MANY
          * BELONGS_TO
             
    分別對應(yīng)FLEA_Db_TableDataGateway表中的 $hasOne,$hasMany,$manyToMany,$belongsTo 屬性

    我們下面就用 老師,學(xué)生,學(xué)生檔案,班級的例子說說這幾個關(guān)系。

    以下是SQL代碼:
     1 //學(xué)生表
     2 Create TABLE `testDB`.`student` (
     3   `stu_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
     4   `stu_name` VARCHAR(20NOT NULL,
     5   `stu_class_id` INTEGER UNSIGNED NOT NULL,
     6   PRIMARY KEY (`stu_id`)
     7 )
     8 
     9 //學(xué)生檔案表
    10 Create TABLE `testDB`.`stu_record` (
    11   `record_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    12   `stu_id` INTEGER UNSIGNED NOT NULL,
    13   `family_add` VARCHAR(150NULL,
    14   `family_tel` VARCHAR(20NULL,
    15   PRIMARY KEY (`record_id`)
    16 )
    17 
    18 //教師表
    19 Create TABLE `testDB`.`teacher` (
    20   `teacher_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    21   `teacher_name` VARCHAR(20NOT NULL,
    22   PRIMARY KEY (`teacher_id`)
    23 )
    24 
    25 //班級表
    26 Create TABLE `testDB`.`classes` (
    27   `class_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    28   `class_name` VARCHAR(20NOT NULL,
    29   PRIMARY KEY (`class_id`)
    30 )
    31 
    32 //由于教師與班級是多對多關(guān)系,所有建立一個中間連接表以表示該關(guān)聯(lián)
    33 Create TABLE `testDB`.`link_teacher_classes` (
    34   `link_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    35   `teacher_id` INTEGER UNSIGNED NOT NULL,
    36   `class_id` INTEGER UNSIGNED NOT NULL,
    37   PRIMARY KEY (`link_id`)
    38 )


    現(xiàn)在,建好表之后,我們還要寫幾個繼承自FLEA_Db_TableDataGateway父類的類,以對應(yīng)數(shù)據(jù)庫中的Student,Teacher,Classes表(連接表不用了)如下:
     1 //學(xué)生表對應(yīng)的類
     2 class Model_Student extends FLEA_Db_TableDataGateway{
     3         var $tableName = 'student';
     4         var $primaryKey = 'stu_id';
     5        
     6         /*
     7            這是一對一關(guān)系,一個學(xué)生對應(yīng)唯一的一個Record檔案
     8            tableClass 對應(yīng)要與之關(guān)聯(lián)一對一的表的對象類,即檔案表的類
     9            foreignKey是在檔案表中,對應(yīng)學(xué)生表的一個外鍵接連字段,
    10            用該字段標(biāo)識該檔案屬于哪個學(xué)生
    11            mappingName 就是用于在你查詢學(xué)生信息時,學(xué)生檔案字段的別名
    12         */
    13         var $hasOne = array(
    14                     'tableClass' => 'Model_Record',
    15                     'foreignKey' => 'stu_id',
    16                     'mappingName' => 'record'
    17         );
    18         /*
    19            這是從屬關(guān)系,一個學(xué)生屬于某一個班級,換過來說就是班級與學(xué)生一對多,
    20            一個班級有多個學(xué)生,而學(xué)生就只屬于一個班級
    21            tableClass 指定該類要與之有從屬關(guān)系的類,這里是班級類
    22            foreignKey 這里指定的是該表里的連接外表的字段,這里是學(xué)生表的班級ID字段
    23            注意:這里的foreignKey指的是本表的字段,而上面hasOne關(guān)系中的foreignKey
    24            指的是外表中的字段,要注意區(qū)分清楚
    25            mappingName這里就不多說了,跟上面的一樣,也是用于顯示區(qū)分的別名
    26         */
    27         var $belongsTo = array(
    28                 array(
    29             'tableClass' => 'Model_Classes',
    30             'foreignKey' => 'stu_class_id',
    31             'mappingName' => 'class'
    32         )
    33         );
    34 }
    35 
    36 //檔案表對應(yīng)的類
    37 class Model_Record extends FLEA_Db_TableDataGateway{
    38         var $tableName = 'stu_record';
    39         var $primaryKey = 'record_id';
    40 }
    41 
    42 //教師表對應(yīng)的類
    43 class Model_Teacher extends FLEA_Db_TableDataGateway{
    44         var $tableName = 'teacher';
    45         var $primaryKey = 'teacher_id';
    46 
    47         /*
    48            這里確立了教師與班級的多對多關(guān)系,一個教師可以教多個班級
    49            而一個班級也有多個教師
    50            tableClass 指定要建立多對多關(guān)系的表的類
    51            joinTable 這個屬性要注意一個,這個是指定教師表與班級表關(guān)系的連接表
    52            由于二維表的數(shù)據(jù)結(jié)構(gòu)的原因,所以多對多關(guān)系要用一個中間表(即連接表)來表示
    53            連接表中就指明兩個表各自的主鍵ID就可以了,以兩個字段作復(fù)合主鍵,如不用復(fù)合
    54            主鍵,就新增加一個字段作主鍵也可,這沒關(guān)系
    55         */
    56         var $manyToMany = array(
    57                 array(
    58             'tableClass' => 'Model_Classes',
    59             'mappingName' => 'class',
    60             'joinTable' => 'link_teacher_classes',
    61         )
    62         );
    63 }
    64 
    65 class Model_Classes extends FLEA_Db_TableDataGateway{
    66         var $tableName = 'classes';
    67         var $primaryKey = 'class_id';
    68 
    69         /*
    70             這里確立了班級與學(xué)生的一對多關(guān)系
    71             tableClass 指定該表的類要與哪個表的類建立一對多關(guān)系
    72             foreignKey 外鍵ID,這里即指定學(xué)生表中定義的班級ID,這個是外表的字段
    73         */
    74         var $hasMany = array(
    75                 array(
    76             'tableClass' => 'Model_Student',
    77             'foreignKey' => 'stu_class_id',
    78             'mappingName' => 'students'
    79         )
    80         );
    81 
    82         var $manyToMany = array(
    83         // 由于多對多關(guān)系是雙向的,所以班級表也可以定義上與教師表的多對多關(guān)系
    84         // 也可以不寫,看需求而定,比如你想查看某個班級信息時,一并顯示該班
    85         // 有多少個任課老師的話,那就在這個班級類里加上關(guān)系,我這里就不寫了。。。
    86         );
    87 }


    以上的代碼就建立好了關(guān)系了,現(xiàn)在只管使用就是了。
    不過還提醒大家一點,在每個關(guān)系里,都有一個 ‘enabled’ 的屬性,如果設(shè)置為 false的話,則是將該關(guān)系禁掉,所以查詢出來的結(jié)果就沒有該關(guān)系的相應(yīng)數(shù)據(jù),這樣可以節(jié)省效率,按需要時才打開相應(yīng)的關(guān)聯(lián),該屬性默認(rèn)為true 可以如下設(shè)置:
    1 array(
    2     'tableClass' => 'Model_Student',
    3     'foreignKey' => 'stu_class_id',
    4     'mappingName' => 'students',
    5     ‘enabled’ => false
    6 )


    現(xiàn)在我們來測試一下數(shù)據(jù)。(事先自行插入幾行數(shù)據(jù)用以測試)
    1 $classManager = FLEA::getSingleton('Model_Classes');
    2 $class =& $classManager->find(array('class_id' => 1));
    3 dump($class);


    出現(xiàn)結(jié)果如下:


    這個例子已含蓋了這四個關(guān)聯(lián)關(guān)系的基本用法了,其它的就由你們來探索了,不久后,我將會發(fā)表一下這此關(guān)聯(lián)方面的高級應(yīng)用,有時間的話會寫寫這方面的東西。敬請期待!


    posted @ 2008-07-29 14:02 姜大叔 閱讀(328) | 評論 (0)編輯 收藏
          這篇文章是接著上一篇,在上一篇的基礎(chǔ)上加了用戶注冊功能,注冊成功后顯示用戶信息,由于時間關(guān)系,沒有詳細(xì)研究實現(xiàn)什么功能例子用于教學(xué),本來我也只是FleaPHP初學(xué)者,所以,雖然例子十分的傻瓜式簡單,但就當(dāng)是我在學(xué)FleaPHP時的快速練習(xí)吧。
          這里只實現(xiàn)了個注冊功能,有經(jīng)驗的應(yīng)該閉上眼睛都能做出來了,所以我這里的只是演示一下FleaPHP的大概操作流程的,也就是它的結(jié)構(gòu)都是差不多,我在之前第一篇的那個Model_User類里,加了幾個方法:
    1     //添加一個新用戶
    2     function addNewUser($user){
    3         return $this->_tbUser->create($user);
    4     }
    5     //用主鍵加載一個用戶
    6     function loadUser($userid){
    7         return $this->_tbUser->find($userid);
    8     }


    并在Default.php里,也就是在Default的Controller里加了一個action與一個方法函數(shù):

     1 function actionRegister(){
     2         $mod_user = new Model_User;
     3         $username = $_POST["username"];
     4         $password = $_POST["password"];
     5         $password2 = $_POST["password2"];
     6        
     7         if(strlen($username< 6){
     8             $message = '用戶名要求6-10位!';
     9             include('app/View/register.php');
    10             return;
    11         }
    12        
    13         if($password != $password2){
    14             $message = '你輸入的密碼不一致,請重新輸入!';
    15             include('app/View/register.php');
    16             return;
    17         }
    18        
    19         if(strlen($password< 6){
    20             $message = '密碼要求6-10位!';
    21             include('app/View/register.php');
    22             return;
    23         }
    24        
    25         $user = array(
    26                     'name'         => $username,
    27                     'password'     => $password
    28                 );
    29         $newUserId = $mod_user->addNewUser($user);
    30        
    31         if($newUserId){
    32             $message = '注冊成功!';
    33             $this->showinfo($newUserId);
    34         }else{
    35             $message = '出現(xiàn)錯誤,注冊失敗!';
    36             include('app/View/error.php');
    37         }
    38     }
    39    
    40     function showinfo($userid){
    41         $mod_user = new Model_User;
    42         $user = $mod_user->loadUser($userid);
    43         include('app/View/userinfo.php');
    44     }


    這都很直觀了,大家注意的是流程的控制與轉(zhuǎn)移,如果是開發(fā)小項目的話,這可能還會覺得麻煩,但當(dāng)項目稍大時,程序結(jié)構(gòu)將會很直觀,控制流程很清淅。

    之后在View文件夾里加了register.php  error.php等View文件,也主要是Html的,應(yīng)盡量把邏輯代碼與UI代碼分開,這里只是初入門篇,遲點將會介紹與Smarty模板技術(shù)結(jié)合使用的文章。

    最終源碼下載:[down=attachments/month_0710/k20071016235619.rar]點擊下載此文件[/down]


    posted @ 2008-07-29 13:58 姜大叔 閱讀(228) | 評論 (0)編輯 收藏
          由于忙,很少時間學(xué)學(xué) FleaPHP 框架,不過之前也看了看學(xué)了點東西,感覺FleaPHP框架還是很不錯的,有良好的MVC模式結(jié)構(gòu),比較方便的數(shù)據(jù)庫操作,好東西不敢獨享,所以獻(xiàn)上我在學(xué)習(xí)FleaPHP中的一點小心得,適合初接觸 FleaPHP 框架的同學(xué),PHP基礎(chǔ)不太好的話,建議先補習(xí)一下PHP再看看這系列的文章。
          本例子是我剛學(xué)FleaPHP框架時的小練習(xí),一步一步循序漸進(jìn),剛開始的例子顯得比較簡單,都只是熟習(xí)他的環(huán)境而已,不過我將采用增量開發(fā)的模式,慢慢完善深入,同學(xué)們記得專心上堂哦,做好功課哦。(文章的末尾將提供完整源代碼打包,由于篇幅有限,所以文章中貼出來的代碼有的只是片段)
          這篇是我寫 FleaPHP 學(xué)習(xí)筆記的開篇,做的是一個簡單的登錄功能,牛刀小試吧,認(rèn)大家認(rèn)識一下 FleaPHP 的MVC結(jié)構(gòu)與基本數(shù)據(jù)庫操作,如果是對 FleaPHP 還不知道是什么東西的話,可以到以下網(wǎng)站了解了解。fleaphp.org

    數(shù)據(jù)庫準(zhǔn)備:數(shù)據(jù)庫里就只有一個表  tb_user   里面有三個字段,id ,name ,password 夠簡單吧[smile]

    我的這個FleaPHP應(yīng)用的目錄結(jié)構(gòu)如下:


    圖中可以看到就一個index.php主頁文件,一個app與一個FLEA文件夾,因為FleaPHP是采用單一入口框架,所以就只有一個index.php文件,所以的請求都經(jīng)由這個文件再進(jìn)行分類分發(fā),這樣可以提高代碼的安全性,可以將程序其它文件放置到URL訪問不到的地方,在index.php里引用該路徑就可以了。不過有點要注意的是文件的路徑的正確性。
    app文件夾就是我的程序代碼放置的地方,里面有Controller,Model,View,Table文件夾,Controller文件夾都是FleaPHP的命名約定的,最好使用這樣的命名,因為會跟據(jù)請求到該文件夾中找相對應(yīng)的類文件的,好,我們先來看看index.php的代碼:
     1 <?php
     2 require("./FLEA/FLEA.php");
     3 FLEA::import(dirname(__FILE__)."/app");
     4 
     5 // 準(zhǔn)備數(shù)據(jù)庫連接信息
     6 $dsn = array(
     7     'driver'        => 'mysql',
     8     'host'          => 'localhost',
     9     'login'         => 'root',
    10     'password'      => 'root',
    11     'database'      => 'test',
    12 );
    13 
    14 set_app_inf('dbDSN',$dsn);
    15 
    16 FLEA::runMVC();
    17 ?>


          就這么個三四行代碼,程序就啟動了,呵呵,不過后面還有呢。。。
    先來解析一下,第一句是 require("./FLEA/FLEA.php"); 就是要先導(dǎo)入FleaPHP的核心引擎,所以之前大家看到了有個FLEA文件夾,就是FLEA的核心引擎啦,這個大家先不用管它,等到要研究他的源代碼時再看吧,平時的使用就看看提供的API文檔就夠了。
          同學(xué)們注意了,F(xiàn)LEA::import(dirname(__FILE__)."/app"); 這句的作用是什么?這個import函數(shù)是FLEA的靜態(tài)函數(shù),用于將你的程序文件夾導(dǎo)入進(jìn)來,如果有玩過Java的同學(xué)應(yīng)該知道多少吧,當(dāng)FleaPHP接收到一個請求時,會分析URL再調(diào)用相對的Controller和Action,
    如:http://localhost/fleatest/index.php?controller=Shop&action=checkout 這里即調(diào)用Shop控制器里面的checkout動作,而FleaPHP怎么知道我的控制器代碼放在哪里呢?就是靠import這個語句了,將程序文件夾導(dǎo)入進(jìn)來之后,F(xiàn)leaPHP會自去到這個文件夾里找Controller文件夾再找Shop.php這個類文件,所以,如果你為了安全起見,將程序文件夾放在了其它訪問不到的地方,就得靠這個import來導(dǎo)入,以FleaPHP能正確找到所需要的Controller。(可能說得啰嗦了[redface],打字累了,燒根煙先,同學(xué)們小息片刻!)

    接下來$dsn這個數(shù)組就是存放你連接數(shù)據(jù)庫的信息啦,聰明的同學(xué)一眼看出來了。之后當(dāng)然要設(shè)置入FleaPHP配置里面啦,用這個set_app_inf('dbDSN',$dsn);,之后,F(xiàn)LEA::runMVC(); 這個就是啟動了。我們輸入的URL是 http://localhost/fleatest/index.php,由于FleaPHP默認(rèn)的Controller是Default,默認(rèn)的Action是Index,所以,這時,F(xiàn)leaPHP就會跳到app/Controller/Default.php這個頁面來,代碼如下:
     1 <?php
     2 FLEA::loadClass("Model_User");
     3 class Controller_Default
     4 {
     5     function actionIndex(){
     6         include('app/View/login.php');
     7     }
     8    
     9     function actionLogin(){
    10         //新建一個對應(yīng)user數(shù)據(jù)表操作的Model對象
    11         $mod_user = new Model_User;
    12         //根據(jù)用戶輸入的用戶名查找數(shù)據(jù)庫有沒有存在
    13         $result = $mod_user->findByName($_POST['username']);
    14         if(empty($result)){
    15             $message = '該用戶不存在!';
    16             include('app/View/login.php');       
    17         }else{
    18             //判斷密碼是否相同
    19             if($result['password'== $_POST['password']){
    20                 $username = $result['name'];
    21                 include('app/View/welcome.php');
    22             }else{
    23                 $message = '密碼不正確,請重新輸入!';
    24                 include('app/View/login.php');
    25             }
    26         }
    27     }
    28 }
    29 ?>


          為什么類名是 Controller_Default ?這都是FleaPHP的命名規(guī)則,大家可以去官網(wǎng)看看它的命名規(guī)則,這里就不多啰嗦了。現(xiàn)在,它將會調(diào)用actionIndex的默認(rèn)action函數(shù),里面只引入了一個php文件,那就是登錄界面的頁面。

          在登錄界面的Form里,設(shè)置好action提交路徑,使它提交到Default控制器的Login動作(action),里面實例化了一個Model對象,該對象是封裝了對表tb_user的操作,之后程序邏輯就是跟據(jù)登錄成功與否來進(jìn)行相應(yīng)的信息表示啦,簡單的實現(xiàn)了從Controller -> Model -> View 的MVC訪問操作流程。
    大概的結(jié)構(gòu)就這么簡單了。

    最后符上源代碼:[down=attachments/month_0710/520071010232245.rar]點擊下載此文件[/down]

    大家如果有什么疑問,可以留言或發(fā)到我郵箱里!


    posted @ 2008-07-29 13:57 姜大叔 閱讀(353) | 評論 (1)編輯 收藏
    緩存

          功能強大的應(yīng)用程序一般都有很大的開銷,通常是數(shù)據(jù)獲取和處理操作帶來的。對于Web應(yīng)用程序,這個問題是由于HTTP協(xié)議的無狀態(tài)性造成的。由于HTTP協(xié)議是無狀態(tài)的,對于每個頁面請求,都要重復(fù)地執(zhí)行相同的操作,而不論數(shù)據(jù)是否修改。要讓應(yīng)用程序在世界范圍最大的網(wǎng)絡(luò)中可用,會使這個問題進(jìn)一步惡化。所以,毫不奇怪,人們總在想方設(shè)法地讓W(xué)eb應(yīng)用程序運行得更高效。對此有一種特別有效的解決方案,這也是最合理的方案之一:將動態(tài)頁面轉(zhuǎn)換成靜態(tài)頁面,只有在頁面內(nèi)容有修改之后才重新構(gòu)建,或者定期地重新構(gòu)建。Smarty提供了這樣一個特性,一般稱為頁面緩存。
        如果要使用緩存,需要首先通過設(shè)置Smarty 的緩存屬性來啟用緩存,如下:
    1 <?php
    2   require("Smarty.class.php");
    3   $smarty = new Smarty;
    4   $smarty->caching = 1;
    5    $smarty->display("news.tpl");
    6 ?>

          啟用緩存后,調(diào)用 display() 和 fetch() 方法在指定模板 (由$cache_dir 屬性指定) 中保存目標(biāo)模板的內(nèi)容。

        處理緩存生命期

          緩存的頁面在由 $cache_lifetime 屬性指定的生命期(以秒為單位)內(nèi)有效,默認(rèn)為3600秒,即1小時。因此,如果希望修改此設(shè)置,就可以設(shè)置這個屬性,如下:
    1 <?php
    2     require("Smarty.class.php");
    3     $smarty = new Smarty;
    4     $smarty->caching = 1;
    5     //設(shè)置生命周期
    6    $smarty->cache_lifetime = 1800;
    7     $smarty->display("news.tpl");
    8 ?>

    在此對象的生命期內(nèi),后續(xù)調(diào)用和緩存的模板都使用此生命期。
        有可能需要覆蓋以前設(shè)置的緩存生命期,從而能分別控制每個模板的緩存生命期。通過將$caching 屬性設(shè)置為2就可以做到這一點,如下:
    1 <?php
    2     require("Smarty.class.php");
    3     $smarty = new Smarty;
    4     $smarty->caching = 2;
    5     $smarty->cache_lifetime = 1200;
    6     $smarty->display("news.tpl");
    7 ?>

    在這里,news.tpl 模板的生命期設(shè)置為20分鐘,它覆蓋了前面設(shè)置的全局生命期值。

    通過 is_cached( ) 消除處理開銷

        如前面所述,緩存模板還能消除處理開銷,如果禁用緩存(只啟用編譯),這些處理開銷總是會發(fā)生。但是,默認(rèn)情況下并沒有啟用緩存。要啟用緩存,需要把處理指令放在 if 條件中,并執(zhí)行 is_cached( )方法,如下:
     1 <?php
     2     require("Smarty.class.php");
     3     $smarty = new Smarty;
     4     $smarty->caching = 1;
     5    
     6     if (! $smarty->is_cached("news.tpl")){
     7         $conn = mysql_connect("localhost","name","pwd");
     8         $db = mysql_select_db("news");
     9         $query = "select * from news";
    10         
    11     }
    12     $smarty->display("news.tpl");
    13 ?>

          在這個例子中,將首先驗證模板news.tpl是否有效。如果有效,則跳過數(shù)據(jù)庫訪問,否則才訪問數(shù)據(jù)庫。

    為每個模板創(chuàng)建多個緩存
       
        任何指定的Smarty模板都可以用于為整個新聞項,博客項等提供一個通用界面。由于同一個模板用來生成不同數(shù)量的不同項,那么如何緩存一個模板的多個實例呢?答案比你想像的要簡單。Smarty的開發(fā)人員實際不已經(jīng)解決了這個問題,可以通過display()方法為緩存模板的每個實例指派一個唯一標(biāo)識符。例如,假設(shè)有一個用生成用戶信息的模板,并希望緩存這個模板的各個實例:
     1 <?php
     2     require("Smarty.class.php");
     3     require("User.class.php");
     4 
     5     $smarty = new Smarty;
     6     $smarty->caching = 1;
     7 
     8     //根據(jù)不同的用戶ID來區(qū)分不同的用戶實例來判斷有沒有被緩存
     9     if(! is_cached("userinfo.tpl",$_GET['userid'])){
    10         $user = new User();
    11 
    12         $smarty->assign("name",$user->getName());
    13         $smarty->assign("address",$user->getAddress());
    14     }
    15     
    16     /*
    17       當(dāng)顯示時也根據(jù)該用戶的ID來區(qū)分將哪個實例進(jìn)行緩存,而不影響其它用戶的緩存
    18     即是用userid 值來區(qū)分同一個緩存模板的不同實例,所有用戶都共用一個模板,
    19     但信息都不盡相同,所以不能統(tǒng)一緩存,要獨立分開緩存
    20    */
    21     $smarty->display("userinfo.tpl",$_GEG['userid']);
    22 ?>

    特別注意下面一行:
        $smarty->display("userinfo.tpl",$_GEG['userid']);
    這一行對于此腳本有兩個功能,一方面獲取名為$_GET['userinfo'] 的 userinfo.tpl 緩存版本,另一方面,如果還不存在這個緩存,則用這個名字來緩存該模板實例。采用這種方式,可以輕松地為指定模板緩存任意數(shù)量的實例。

    關(guān)于緩存的結(jié)語

        模板緩存大大提升了應(yīng)用程序的性能,如果決定將Smarty集成到工程中來,就應(yīng)當(dāng)認(rèn)真地考慮緩存。但是,因為大多數(shù)強大的Web應(yīng)用程序功能都體現(xiàn)在其動態(tài)性上,所以一方面要考慮到性能提升,另一方面也要考慮到緩存頁面隨時間是否仍有效,要在這二者之間進(jìn)行權(quán)衡。
    posted @ 2008-07-29 13:55 姜大叔 閱讀(220) | 評論 (0)編輯 收藏
    僅列出標(biāo)題
    共4頁: 上一頁 1 2 3 4 下一頁 
    主站蜘蛛池模板: 性无码免费一区二区三区在线| 亚洲国产成人久久| 亚洲欧洲国产成人综合在线观看| 日韩免费无码一区二区视频| 夫妻免费无码V看片| 91免费资源网站入口| 91网站免费观看| 性短视频在线观看免费不卡流畅| 69视频在线观看高清免费| 久久久久国产精品免费网站| 亚洲成人免费在线| 100部毛片免费全部播放完整| 国产成人精品免费视频大全麻豆| 波多野结衣免费在线观看| 国产大片线上免费观看| 天天看片天天爽_免费播放| 国产一级淫片视频免费看| 国产jizzjizz视频全部免费| 亚洲Aⅴ无码一区二区二三区软件 亚洲AⅤ视频一区二区三区 | 亚洲动漫精品无码av天堂| 亚洲欭美日韩颜射在线二| 日本亚洲视频在线| 91视频免费观看| 久久久久亚洲AV成人片| 国产专区一va亚洲v天堂| 亚洲精品乱码久久久久久中文字幕 | 成**人免费一级毛片| 在线视频免费国产成人| 亚洲综合激情另类专区| 亚洲中文久久精品无码ww16| 色婷婷六月亚洲婷婷丁香| 亚洲乱码中文字幕小综合| 国产精品亚洲专一区二区三区| 一本久久A久久免费精品不卡| 久久精品视频免费看| 国产在线观看免费观看不卡| 免费人成在线观看播放国产| 亚洲精品无码不卡在线播放HE| 亚洲精品中文字幕无码AV| 亚洲JLZZJLZZ少妇| 全黄大全大色全免费大片|