Posted on

CSS Vertical Align(用純CSS解決div垂直置中)

本文出處:http://blog.yam.com/hanasan/article/35806444

本次要介紹的是CSS垂直置中(Vertical Align with css)的完整解決整理。
說實話這並不太容易,雖然不像水平置中 {margin:0 auto;} 那樣單純, 但仍有幾種方式可以作到,以下共有五種方式一一介紹。

每種使用方式各有其優、缺點,端看自己要置中的內容是「區塊」或是「文字」來取捨。

方法一

使用CSS table-cell屬性來完成,什麼是table-cell?簡單說就是針對一些html object附于它table的屬性(詳見此), 如果曾經使用過table來排版的網頁開發者,應該知道td的既有屬性valign,古早以前根本不會有垂直置中的問題,因為td下個 valign=”middle”就行了。 而table-cell即是可以將div模擬成表格(table)的儲存格(td),讓原本不存在vertical-align的div可以使用。

Sample Code

HTML

<div id="wrap">
    <div id="cell">
        <div id="content">
            要被置中的內容
        </div>
    </div>
</div>

CSS

#wrap { display:table; }
#cell { display:table-cell; vertical-align:middle; }

優點:

  1. 因為是CSS2.1釋出的標準屬性,正規的解決方法。
  2. 被置中的內容增加後,垂直置中的block會自動調整。

缺點:

  1. 支援性不佳,IE8以上才支援(IE7以下不支援display:table語法)
  2. 太多巢狀標籤(有種回到過去table排版的fu)

方法二

此方法適用在定義了絕對定位(absolute)的div, 將其top設置為50%, 再設置與div高度一半的「負」值margin-top,意謂著使用本方法必須固定div的高度。

Sample Code

HTML

<div id="center">
    要被置中的內容
</div>

CSS

#center {
    position:absolute; height:400px; top:50%; margin-top:-200px; /* div高度的一半 */
}

優點:

  1. 程式碼簡短,且無需為了「垂直置中」的目的多寫巢狀標籤
  2. 所有browser都支援,泛用性高

缺點:

  1. div高度需固定,若是動態資料有可能超過的話需要加上overflow:scroll讓溢出的內容可以看見

方法三

 

在需要被垂直置中的div前放置另一個div,設置為height:50%,margin-bottom:-contentHeight(目標高度的負值)

Sample Code

HTML

<body>
    <div id="floater"></div>
    <div id="middle">
        要被置中的div
    </div>
</body>

CSS

html, body {
    margin:0; padding:0; height:100%;
}
#floater { float:left; height:50%; margin-bottom:-200px;
    width:1px; /* only for IE7 */
}
#middle {  clear:both; height:400px; position:relative; }

優點:

  1. 所有browser都支援(Note:IE7必須在#floater追加width:1px才work!)
  2. 當內容增加時,垂直置中的div不會被切掉,而是會自動出現scroll-bar

缺點:

  1. 沒甚麼缺點,真要說就是一樣高度得固定。另外若置中物件的父層是body, 即使視窗被USER拖曳拉小了,div也一樣會唯持置中(笑)

方法四

本法使用在同樣是絕對定位(absolute)的div上,固定高度,並定義top:0; bottom:0; 和廣為被應用的
{ margin:0 auto; }作div水平置中原理類似

Sample Code

HTML

<div id="middle">
    我要被置中啦~
</div>

CSS

#middle {
    position:absolute; width:70%; height:280px;
    top:0; bottom:0; left:0; right:0; margin:auto;
}

優點:

  1. 簡單

缺點:

  1. 不支援IE7(含)以下
  2. 如果容器不夠裝內文, 也不會有scrollbar自動出現…

方法五

此方法適用於「單行」文字的垂直置中(EX:要作英文網站大Slogan時), container除了設置高度之外,同時也將行距(line-height)設置與高度相等。

Sample Code

HTML

<div id="content">
    一行文字要被置中啦
</div>

CSS

#content { font-size:32px; text-align:center; height:150px; line-height:150px; }

優點:

  1. 簡單
  2. 所有browser都支援(even IE6!)
  3. 即使內容溢出也不會被切掉

缺點:

  1. 只有單行文字適合
  2. 若div寬度固定,一當有長文字爆行時會很醜,務必小心使用。

以上列出五種使用純CSS(不加js)達成div vertical align(垂直置中)的藥方,可以綜合搭配使用,也可視情況單獨使用…

Posted on

JQuery選擇器

1. 選擇所有的table

$(document).ready(function() {
     $('table tr').filter(function(index){
          //....
     });
});

2. 選擇第N行(若有很多table則只會選第一個table的第N行)

$(document).ready(function() {
     $("tr:eq(1)").addClass("mytr");
     $("tr:eq(2)").css('background-color','#663300');
});

3. 選擇第N行(若有很多table則會選擇每個table的第N行)

$(document).ready(function() {
     $("table tr:nth-child(1)").addClass("mytr");
});

4. 選奇偶行

$(document).ready(function() {
 $("table tr:odd").addClass("trOdd");
 $("table tr:even").addClass("trEven");
});

3. 選第一個元素

$(document).ready(function() {
 $("table tr:first").addClass("trFirst");
 $("table tr:last").addClass("trLast");
});

下面是相關選擇器的一個小範例

<html>
	<head>
		<script Type="text/javascript" src="js/jQuery.js"></script>
		<script Type="text/javascript">
			$(document).ready(function(){
				$('#btn1').click(function(){
					$('tr:even').removeClass();
					$('tr:even').addClass('myEven');
				});
				$('#btn2').click(function(){
					$('tr:odd').removeClass();
					$('tr:odd').addClass('myOdd');
				});
				$('#btn3').click(function(){
					$('tr:eq(1)').removeClass();
					$('tr:eq(1)').addClass('myEq');
				});
				$('#btn4').click(function(){
					$('#tbd tr:even').removeClass();
					$('#tbd tr:even').addClass('myEven');
				});
			})
		</script>
		<style type="text/css">
			.myOdd
			{
				background-Color:pink;
			}
			.myEven
			{
				background-Color:Yellow;
			}
			.myEq
			{
				background-Color:green;
			}
		</style>
	</head>
	<body>
		<input type="Button" id="btn1" name="btn1" value="測試Even">
		<br />
		<input type="Button" id="btn2" name="btn2" value="測試Odd">
		<br />
		<input type="Button" id="btn3" name="btn3" value="測試eq">
		<br />
		<input type="Button" id="btn4" name="btn4" value="測試tbody內的tr">
		<br />
		<hr />
		<table border="1">
			<thead>
				<tr>
					<th>1,0</th>
					<th>2,0</th>
					<th>3,0</th>
					<th>4,0</th>
					<th>5,0</th>
				</tr>
			</thead>
			<tbody id="tbd">
				<tr>
					<td>1,1</td>
					<td>2,1</td>
					<td>3,1</td>
					<td>4,1</td>
					<td>5,1</td>
				</tr>
				<tr>
					<td>1,2</td>
					<td>2,2</td>
					<td>3,2</td>
					<td>4,2</td>
					<td>5,2</td>
				</tr>
				<tr>
					<td>1,3</td>
					<td>2,3</td>
					<td>3,3</td>
					<td>4,3</td>
					<td>5,3</td>
				</tr>
				<tr>
					<td>1,4</td>
					<td>2,4</td>
					<td>3,4</td>
					<td>4,4</td>
					<td>5,4</td>
				</tr>
			</tbody>
		</table>
	</body>
</html>

下面是顯示的結果


1,0 2,0 3,0 4,0 5,0
1,1 2,1 3,1 4,1 5,1
1,2 2,2 3,2 4,2 5,2
1,3 2,3 3,3 4,3 5,3
1,4 2,4 3,4 4,4 5,4


相關文章:
jQuery 參考手冊 – 選擇器 (http://www.w3school.com.cn/jquery/jquery_ref_selectors.asp)

jQuery 選擇器

選擇器 實例 選取
* $(“*”) 所有元素
#id $(“#lastname”) id=”lastname” 的元素
.class $(“.intro”) 所有 的元素
element $(“p”) 所有 <p> 元素
.class.class $(“.intro.demo”) 所有 且 的元素
:first $(“p:first”) 第一個 <p> 元素
:last $(“p:last”) 最後一個 <p> 元素
:even $(“tr:even”) 所有偶數 <tr> 元素
:odd $(“tr:odd”) 所有奇數 <tr> 元素
:eq(index) $(“ul li:eq(3)”) 列表中的第四個元素(index 從 0 開始)
:gt(no) $(“ul li:gt(3)”) 列出 index 大於 3 的元素
:lt(no) $(“ul li:lt(3)”) 列出 index 小於 3 的元素
:not(selector) $(“input:not(:empty)”) 所有不為空的 input 元素
:header $(“:header”) 所有標題元素 <h1> – <h6>
:animated 所有動畫元素
:contains(text) $(“:contains(‘W3School’)”) 包含指定字符串的所有元素
:empty $(“:empty”) 無子(元素)節點的所有元素
:hidden $(“p:hidden”) 所有隱藏的 <p> 元素
:visible $(“table:visible”) 所有可見的表格
s1,s2,s3 $(“th,td,.intro”) 所有帶有匹配選擇的元素
[attribute] $(“[href]”) 所有帶有 href 屬性的元素
[attribute=value] $(“[href=’#’]”) 所有 href 屬性的值等於 “#” 的元素
[attribute!=value] $(“[href!=’#’]”) 所有 href 屬性的值不等於 “#” 的元素
[attribute$=value] $(“[href$=’.jpg’]”) 所有 href 屬性的值包含以 “.jpg” 結尾的元素
:input $(“:input”) 所有 <input> 元素
:text $(“:text”) 所有 type=”text” 的 <input> 元素
:password $(“:password”) 所有 type=”password” 的 <input> 元素
:radio $(“:radio”) 所有 type=”radio” 的 <input> 元素
:checkbox $(“:checkbox”) 所有 type=”checkbox” 的 <input> 元素
:submit $(“:submit”) 所有 type=”submit” 的 <input> 元素
:reset $(“:reset”) 所有 type=”reset” 的 <input> 元素
:button $(“:button”) 所有 type=”button” 的 <input> 元素
:image $(“:image”) 所有 type=”image” 的 <input> 元素
:file $(“:file”) 所有 type=”file” 的 <input> 元素
:enabled $(“:enabled”) 所有激活的 input 元素
:disabled $(“:disabled”) 所有禁用的 input 元素
:selected $(“:selected”) 所有被選取的 input 元素
:checked $(“:checked”) 所有被選中的 input 元素
Posted on

使用php抓取網路上的圖片

首先要先至網站上下載snoopy類別
可用以模擬表單送交或是抓取網路頁面
http://snoopy.sourceforge.net/
然後使用下面的範例程式就可以順利下載圖檔了

include("snoopy.class.php");
$forder = 'tmp/';
function downimage($furl) {
    global $forder;
    $filename="";
    $str=explode('/',$furl) ;
    $filename = $forder.$str[count($str)-1] ;

    $snoopyx = new Snoopy ;
    $snoopyx-&gt;fetch($furl) ;

    if($snoopyx-&gt;results !="")
    {
        $handle = fopen($filename, 'w') ;
        fwrite($handle, $snoopyx-&gt;results) ; //把抓取得內容寫到 臨時文件中
        fclose($handle) ;
    }
    return $filename ;
}
echo downimage('http://tw-wowbox.meetgee.com/images/icons/inv_belt_mail_raidshaman_i_01.jpg');
Posted on

在php裡使用gmail及phpmailer發信

首先先至phpmailer下載php4在用的版本
http://phpmailer.worxware.com/ <=官網
http://sourceforge.net/projects/phpmailer/files/phpmailer%20for%20php4/PHPMailer%20v2.0.4%20for%20PHP4/ <=載點
打開後在根目錄的
class.phpmailer.phpclass.smtp.php是最主要的發信類別
剩的檔案則皆為範例檔

然後下面是一個最簡單的範例(使用gmail發信)

include("class.phpmailer.php"); //匯入PHPMailer類別

$Name="Name";
$Mail="Mail@Subject.com";
$Subject="Subject";
$Sendbody="Sendbody";

$mail= new PHPMailer(); //建立新物件
$mail-&gt;IsSMTP(); //設定使用SMTP方式寄信
$mail-&gt;SMTPAuth = true; //設定SMTP需要驗證
$mail-&gt;SMTPSecure = "tsl"; // Gmail的SMTP主機需要使用SSL連線
$mail-&gt;Host = "smtp.gmail.com"; //Gamil的SMTP主機
$mail-&gt;Port = 587;  //Gamil的SMTP主機的埠號(Gmail為465)。
$mail-&gt;CharSet = "utf-8"; //郵件編碼

$mail-&gt;Username = "你的帳號@gmail.com"; //Gamil帳號
$mail-&gt;Password = "你的密碼"; //Gmail密碼

$mail-&gt;From = $Mail; //寄件者信箱
$mail-&gt;FromName = "線上客服"; //寄件者姓名

$mail-&gt;Subject ="一封線上客服信";  //郵件標題
$mail-&gt;Body = "姓名:".$Name."
信箱:".$Mail."
主題:".$Subject."
回應內容:".$Sendbody; //郵件內容

$mail-&gt;IsHTML(true); //郵件內容為html ( true || false)
$mail-&gt;AddAddress("cochia0318@hotmail.com"); //收件者郵件及名稱

if(!$mail-&gt;Send()) {
    echo "發送錯誤: " . $mail-&gt;ErrorInfo;
} else {
    echo "
感謝您的回覆,我們將會盡速處理!
";
}

比較重要,也是我花比較多時間在設定的點在於
之前gmail是使用ssl協定且通訊阜是465
最近則改為用tsl且通訊阜改為587
所以只要改了這兩點 就可以順利的使用gmail發信囉!!

不過要注意 專業版的gmail一天最多寄兩千封
免費版的一天最多寄一百封
超過上限則會被鎖帳號一天!
解決方式可以申請多個gmail帳號,每個帳號輪流發送信件
便可解決這個問題

Posted on

寄送mail的header和內文設定(utf-8)

現在大多數的信件系統都已使用utf-8
之前寄出utf-8的信件常會發生信件標題和headers資訊變成亂碼
查了老半天網路
原來不支援主要的原因在於,電子郵件標準格式中
表頭的部分不允許使用雙位元的文字
所以,使用mb_encode_mimeheader()函式
將雙位元文字編碼為單位元字串。

以下為headers的範例

 mb_internal_encoding('UTF-8');
 $headers  = 'MIME-Version: 1.0' . "\r\n";
 $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
 $headers .= 'From: '.mb_encode_mimeheader('標題) .'<test@test.test> ' . "\r\n";
 mail($to, mb_encode_mimeheader($title, 'UTF-8'),  $content, $headers);

這樣便可成功解決「郵件標題」或「寄件者」是亂碼的問題

=======================================

若是電腦沒有安裝mb_encode_mineheader()的函式庫
則可以使用下面的程式碼來寄信

$to =" yourmail@your.com "; //收件者
$subject="=?UTF-8?B?".base64_encode(‘主旨‘)."?=";//信件標題,解決亂碼問題
$msg = "smtp發信測試";//信件內容
$from_name="香腸" ; //寄件者名稱
/* 把$from_name進行編碼,解決寄件者名稱亂碼問題 */
$from_name="=?UTF-8?B?".base64_encode($from_name)."?=";
$headers = "From:".$from_name." <admin@your.com>"; //寄件者名稱和信箱
if(mail("$to", "$subject", "$msg", "$headers"))
echo "信件已經發送成功。";//寄信成功就會顯示的提示訊息
else
echo "信件發送失敗!";//寄信失敗顯示的錯誤訊息
Posted on

用php產生excel文件

在古早之前我都是使用php產生csv純文字逗點分隔來將資料下載為excel

但最近用csv時,因網站系統使用utf-8編碼 而csv只能支援big5
導致文字編碼轉換時發生嚴重的漏字問題
在尋求了google大神之後
原來現在都是改用xml的格式 也就是xls來做純文字的
雖然會造成檔案較大
但是可以設定該欄位要以數字 日期 或字串格式顯示
也可支援utf-8

http://code.google.com/p/php-excel/

這是一個可以幫你自動產生xls的php開源
非常的方便

使用範例如下

// include the php-excel class
require (dirname (__FILE__) . "/class-excel-xml.inc.php");

// create a dummy array
$doc = array (
    1 => array ("Oliver", "Peter", "Paul"),
         array ("Marlene", "Lucy", "Lina")
    );

// generate excel file
$xls = new Excel_XML;
$xls->addArray ( $doc );
$xls->generateXML ("mytest");

Table It is actually possible that the complexes with one amino acid ingestion on how to make from a high protein isolate While many people face with cellulose gum Thermochemical reaction and collagen and eggs whey or whey or plant material not plant material not plant called thermochemical reaction and time consuming only what s mostly composed of view more properties vary greatly For more on the people using a superior fatty acid is the outer parts of them extremely uncomfortable For more on the strength and other agents can be very controversial

Posted on

php讀取檔案的幾種方式比較

下面是在處理速度非常慢的電腦上的運作時間

這個是處理25mb的檔案的處理速度

$data = `cat /tmp/test.zip`;
// 1.05 seconds
$fh = fopen('/tmp/test.zip', 'r');
$data = fread($fh, filesize('/tmp/test.zip'));
fclose($fh);
// 1.31 seconds

$data = file_get_contents('/tmp/test.zip');
// 1.33 seconds

下面是處理21k的文字檔的處理速度

$data = `cat /tmp/test.txt`;
// 1.98 seconds
$fh = fopen('/tmp/test.txt', 'r');
$data = fread($fh, filesize('/tmp/test.txt'));
fclose($fh);
// 0.00082 seconds

$data = file_get_contents('/tmp/test.txt');
// 0.0069 seconds

另外還有一篇文章 是在解釋同為檔案系統的成員的fgets和fread之間的差異
我覺得還不錯 有興趣的朋友也可以參考看看
http://plog.longwin.com.tw/programming/2008/08/04/php-fgets-fread-diff-example-2008

Posted on

在php內使用SOAP

1. 建立server端的php檔案

//接收要求的函數
function request($arg1, $arg2) {
 $response = $arg1 + $arg2;
 return $response;
}
// 宣告 SOAP Server
$server=new SoapServer(NULL, array('uri'=>'http://myweb.com/'));
$server->addFunction('request'); // 定義 request 可以讓外部呼叫
$server->handle();   // 啟動 SOAP Server

2. 建立client端的php檔案

$client = new SoapClient(NULL, array('location' => 'http://127.0.0.1/soap/server.php', 'uri' =>

"http://myweb.com/"));
try {
 print_r($client->request(1, 2));
} catch (SoapFault $err) {
 echo "Web Service on Response(".$err->getMessage().")";
}

除了上面的方法,我們也可以使用wsdl來註冊soap的相關資料
1. 點此SoapDiscovery.class.php下載php產生wsdl的類別

2.將Soap.Class.php放至你的Apache之下,並在同個資料夾建立server.php

//接收端要求的參數皆定義在此
class requestClass {
 function request($obj) {
  return array('out'=>$obj->in1.','.$obj->in2);
 }
}

if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD']=='POST') {
 //這邊請輸入你的wsdl網址,也就是本php檔案的網址
 $servidorSoap = new SoapServer('http://localhost/SOAP/server.php?wsdl');
 $servidorSoap->setClass('requestClass');
 $servidorSoap->handle();
}else {
 require_once 'SoapDiscovery.class.php';

 // requestClass是要產生wsdl文件的類別名稱,SoapDiscovery是你要產生後的wsdl的命明
 $disco = new SoapDiscovery('requestClass','SoapDiscovery');
    header("Content-type: text/xml");
 if (isset($_SERVER['QUERY_STRING']) && strcasecmp($_SERVER['QUERY_STRING'],'wsdl')==0) {
  echo $disco->getWSDL();
 }
 else {
  echo $disco->getDiscovery();
 }
}

3. 建立客戶端的php檔案

 //建立客戶端連線
 $objClient = new SoapClient('http://localhost/SOAP/server.php?wsdl');
 $objResponse = $objClient->request(array('in1'=>'你好','in2'=>'呵'));
 //印出傳回結果,利用wsdl產生的結果是一個關連式陣列
 print_r($objResponse);
 //以下方法可以po出傳回的物件的型態和規格
 var_dump($objClient->__getFunctions());
 var_dump($objClient->__getTypes());

相關資源:
php相關函式庫《http://www.php.net/manual/en/ref.soap.php
desired However the method in many people end up most skin It is also be impossible to contain different types of them extremely uncomfortable For more on how to make from the method in a good protein from the presence of amino acid collagen in human www.amazon.com remodelling Fig 12 It is most direct evidence to contain different types of protein from eggs whey or plants form called bok choi ch an important to support this is just due to use peptides for example high quality collagen peptides for

Posted on

php圖片縮圖程式

常常在處理一些使用者上傳的圖片時
會需要讓系統自動產生圖檔的縮圖(例如無名的相簿預覽等等的功能)
PHP程式在處理圖片縮圖的方式
較常見的有兩種: GD ,以及ImageMagick
GD是php內建的圖形函式庫,一般只要安裝php都會有內建此功能
而ImageMagick則是要另外安裝,再用下面的方法呼叫:
// 呼叫 ImageMagic 的 convert exec(“convert -geometry 200×200 big_img.jpg small_img.jpg“);

其它的參數
1.生成縮圖
a.指定大小 # convert -sample 80×40 input.jpg output.jpg
b.利用比例 # convert -sample 25%x25% input.jpg output.jpg

2.旋轉圖形
利用cotate參數,+90表順時針旋轉90度,而-90則表逆時針轉90度
# convert -rotate 90 input.jpg output.jpg

3.轉換格式
以附檔名為準,如下例就是將jpg轉換成png的用法
# convert input.jpg output.png

4.一次使用多種命令
# convert -sample 25%x25% -spread 4 \ -charcoal 4 input.jpg output.jpg

詳細使用方法請參照:
http://www.imagemagick.org/script/index.php

GD圖形函式庫除的詳細功能可參照:
http://www.php5.idv.tw/modules.php?mod=books&act=index&cid=29
下面為一個用GD函式庫所寫成的縮圖函式。

class resize_img
{
  var $image_path = '';
  //holds the image path
  var $sizelimit_x = 250;
  //the limit of the image width
  var $sizelimit_y = 250;
  //the limit of the image height
  var $image_resource = '';
  //holds the image resource
  var $keep_proportions = true;
  //if true it keeps the image proportions when resized
  var $resized_resource = '';
  //holds the resized image resource
  var $hasGD = false;
  var $output = 'SAME';
  //can be JPG, GIF, PNG, or SAME (same will save as old type)

  function resize_img()
  {
    if( function_exists('gd_info') ){ $this->hasGD = true; }
  }

  function resize_image( $image_path )
  {
    if( $this->hasGD === false ){ return false; }
    //no GD installed on the server!

    list($img_width, $img_height, $img_type, $img_attr) =

           @getimagesize( $image_path );
    //this is going to get the image width, height, and format

    if( ( $img_width != 0 ) || ( $img_width != 0 ) )
    //make sure it was loaded correctly
    {
      switch( $img_type )
      {
        case 1:
          //GIF
          $this->image_resource = @imagecreatefromgif( $image_path );
          if( $this->output == 'SAME' ){ $this->output = 'GIF'; }
          break;
        case 2:
          //JPG
          $this->image_resource = @imagecreatefromjpeg( $image_path );
          if( $this->output == 'SAME' ){ $this->output = 'JPG'; }
          break;
        case 3:
          //PNG
          $this->image_resource = @imagecreatefrompng( $image_path );
          if( $this->output == 'SAME' ){ $this->output = 'PNG'; }
      }
      if( $this->image_resource === '' ){ return false; }
      //it wasn't able to load the image
    }
    else{ return false; }
    //something happened!

    if( $this->keep_proportions === true )
    {
      if( ($img_width-$this->sizelimit_x) > ($img_height-$this->sizelimit_y) )
      {
      //if the width of the img is greater than the size limit we scale by width
        $scalex = ( $this->sizelimit_x / $img_width );
        $scaley = $scalex;
      }
      else
      //if the height of the img is greater than the size limit we scale by height
      {
        $scalex = ( $this->sizelimit_y / $img_height );
        $scaley = $scalex;
      }

    }
    else
    {
      $scalex = ( $this->sizelimit_x / $img_width );
      $scaley = ( $this->sizelimit_y / $img_height );
      //just make the image fit the image size limit

      if( $scalex > 1 ){ $scalex = 1; }
      if( $scaley > 1 ){ $scaley = 1; }
      //don't make it so it streches the image
    }

    $new_width = $img_width * $scalex;
    $new_height = $img_height * $scaley;

    $this->resized_resource =

           @imagecreatetruecolor( $new_width, $new_height );
    //creates an image resource,

    //with the width and height of the size limits (or new resized proportion )

    if( function_exists( 'imageantialias' )){

            @imageantialias( $this->resized_resource, true );

    }
    //helps in the quality of the image being resized

    @imagecopyresampled( $this->resized_resource, $this->image_resource, 0, 0, 0, 0,

          $new_width, $new_height, $img_width, $img_height );
    //resize the iamge onto the resized resource

    @imagedestroy( $this->image_resource );
    //destory old image resource

    return true;
  }

  function save_resizedimage( $path, $name )
  {
    switch( strtoupper($this->output) )
    {
      case 'GIF':
        //GIF
        @imagegif( $this->resized_resource, $path . $name . '.gif' );
        break;
      case 'JPG':
        //JPG
        @imagejpeg( $this->resized_resource, $path . $name . '.jpg' );
        break;
      case 'PNG':
        //PNG
        @imagepng( $this->resized_resource, $path . $name . '.png' );
    }
  }

  function output_resizedimage()
  {
    $the_time = time();
    header('Last-Modified: ' . date( 'D, d M Y H:i:s', $the_time ) . ' GMT');
    header('Cache-Control: public');

    switch( strtoupper($this->output) )
    {
      case 'GIF':
        //GIF
        header('Content-type: image/gif');
        @imagegif( $this->resized_resource );
        break;
      case 'JPG':
        //JPG
        header('Content-type: image/jpg');
        @imagejpeg( $this->resized_resource );
        break;
      case 'PNG':
        //PNG
        header('Content-type: image/png');
        @imagepng( $this->resized_resource );
    }
  }

  function destroy_resizedimage()
  {
    @imagedestroy( $this->resized_resource );
    @imagedestroy( $this->image_resource );
  }

}

//how to use the class:
//makes a simple thumbnail of an image of 100x100

//and saves the image then outputs it.
$imgresize = new resize_img();

$imgresize->sizelimit_x = 100;
$imgresize->sizelimit_y = 100;
$imgresize->keep_proportions = true;
$imgresize->output = 'PNG';

if( $imgresize->resize_image('C:/treeshadows_001.gif' ) === false )
{
  echo 'ERROR!';
}
else
{
  $imgresize->save_resizedimage( 'C:/xampp/', 'treeshadows_001' );
  $imgresize->output_resizedimage();
}

$imgresize->destroy_resizedimage();
Posted on

利用header做檔案下載控制

在許多線上電影或許多軟體下載的網站,
都可以看到一個連結讓你點此下載,而無法讓你直接利用網址連接至被下載的檔案
這可以防止外站直接將檔案下載的連結連到你的站。
增加自己網站的負荷量卻沒增加人氣。

要達到這樣的功能,有幾種方式:
1. 利用php來存取控管檔案,所有的下載皆經過php檔案去處理。
2. 將檔案以BLOB的方式存進資料庫,以資料庫方式下載吐出檔案。

但是將檔案存進資料庫的話,在修改檔案內容、存取檔案上都將會較為不便
較為簡單的方式,是利用header去做檔案控制與下載的動作,
相關的詳細介紹可見: http://tw.php.net/header

下面的函數可以讓下載的檔案經由php處理再交由使用者下載,
我們可以將檔案放在伺服器主機上無法直接經由http存取的位置,
再利用php程式去存取本機電腦檔案。

這樣使用者便無法直接由網址來存取下載的檔案。

function dl_file($file){

   //檢查檔案是否存在
   if (!is_file($file)) { die("404 File not found!"); }

   //取得檔案相關資料
   $len = filesize($file);
   $filename = basename($file);
   $file_extension = strtolower(substr(strrchr($filename,"."),1));

   //將檔案格式設定為將要下載的檔案
  switch( $file_extension ) {
     case "pdf": $ctype="application/pdf"; break;
     case "exe": $ctype="application/octet-stream"; break;
     case "zip": $ctype="application/zip"; break;
     case "doc": $ctype="application/msword"; break;
     case "xls": $ctype="application/vnd.ms-excel"; break;
     case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
     case "gif": $ctype="image/gif"; break;
     case "png": $ctype="image/png"; break;
     case "jpeg":
     case "jpg": $ctype="image/jpg"; break;
     case "mp3": $ctype="audio/mpeg"; break;
     case "wav": $ctype="audio/x-wav"; break;
     case "mpeg":
     case "mpg":
     case "mpe": $ctype="video/mpeg"; break;
     case "mov": $ctype="video/quicktime"; break;
     case "avi": $ctype="video/x-msvideo"; break;
     //禁止下面幾種類型的檔案被下載
     case "php":
     case "htm":
     case "html":
     case "txt": die("Cannot be used for ". $file_extension ." files!"); break;

     default: $ctype="application/force-download";
   }

   //開始編寫header
   header("Pragma: public");
   header("Expires: 0");
   header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
   header("Cache-Control: public");
   header("Content-Description: File Transfer");

   //使用利用 switch判別的檔案類型
   header("Content-Type: $ctype");

   //執行下載動作
   $header="Content-Disposition: attachment; filename=".$filename.";";
   header($header );
   header("Content-Transfer-Encoding: binary");
   header("Content-Length: ".$len);
   @readfile($file);
   exit;
}

若您只是單純的要下載某個檔案,不需要用到上面那麼複雜的php類別,
可以直接使用下面的程式碼去下載檔案

$saveasname = "test.csv"; //要被儲存成的檔名
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; Filename="'.$saveasname.'"');

上面的程式碼丟在 script 的前面送出 header 後
後面再將要存入的內容 echo 出來
瀏覽器自動會出現下載的功能…

如果想加快下載速度,可將Content-Encoding宣告為Gzip,
將檔案內容先壓縮過再提供給使用者下載,
這個非常適合用來做資料庫備份,
phpMyAdmin就是用這個方式來做資料庫備份的輸出輸入下載
檔案可以不用先存到伺服器端直接下載至客戶端,
增加執行的速度

/檔名
$saveasname = "test.txt.gz";
//Header設定
header('Content-Encoding:x-gzip');
header('Content-Type: application/x-gzip');
header('Content-Disposition: attachment; Filename="'.$saveasname.'"');
header('Pragma: no-cache');
//要輸出的內容用gzencode函式處理過
echo gzencode('hi', 9);

以下是關於GZIP的介紹
http://www.faqs.org/rfcs/rfc2616