PHP字串長度找子字串與取代字串的常用函數

PHP在字串的操作上,有非常多的相關函數可以使用,我們在這裡只介紹經常會使用到的字串操作函數。像是如何取得字串的長度、在某一個字裏面尋找子字串首次出現的位置、以及字串的取代函數...等等。這些都是在編寫程式的時候,頻繁被程式設計師使用到的基礎函數。 取得字串長度 <?...

2014年9月5日 星期五

如何實作Android Webservice Client呢?

前言

何謂ksaop2-android計劃呢?它是一個由Third party所開發的一個輕量級的SOAP(Simple Object Access Protocol;簡單物件存取協定) Webservice的公用函式庫,非常適合應用在Android作業系統與外部跨系統間的資料交換。在開始介紹之前,我們先來談一談SOAP是一種使用於互連網上、以XML為訊息交換格式,在跨不同系統之間的資料交換的規範協定。下面我們主要讓各位了解Android平台要如何呼叫外部的Webservice服務。

Ksoap Client操作介面

在這個小節中,將分成用戶介面(UI)顯示和佈置UI元件的XML設定檔兩個部份來探討:
1.用戶介面(UI)顯示,故名思義指的是使用者在Android行動裝置上所呈現的畫面,如圖1所示。
ksaop_ws
圖1. 以ksoap呼叫外部webservice的操作畫面

2.佈置UI元件的XML設定檔(activity_soap_test.xml),是指對映到操作畫面的的每個元素的描述UI元件的定義文件。


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/et_inputname"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/calculateBtn"
        android:layout_alignBottom="@+id/calculateBtn"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/btn_callws"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/btn_callws"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:onClick="processData"
        android:text="呼叫Webservice" />

    <TextView
        android:id="@+id/tv_showme"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/et_inputname"
        android:layout_below="@+id/btn_callws"
        android:layout_marginLeft="84dp"
        android:layout_marginTop="42dp"
        android:text="Show me!!"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>


Ksoap Client商業邏輯


當使用者按下呼叫webservice的按鈕,會觸發執行呼叫外部webserivce的商業邏輯的程式碼(SoapTest.java),舉例來說,使用者只要於操作畫面輸入Kingdom,稍後按下呼叫webservice按鈕,伺服器立即回傳Hello, Kingdom!結果到使用者畫面上。


package test.android.protocol;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import test.android.R;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class SoapTest extends Activity {
 
 private static final String NAMESPACE = "http://ws.yourcompany.com/";
 //將your IP address取代為你的測試主機位址
 private static String URL = "http://your IP address:8080/WSTest/WSGreetingsPort?WSDL";  
 private static final String METHOD_NAME = "hello";
 private static final String SOAP_ACTION =  "http://ws.yourcompany.com/hello";  

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_soap_test);
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.soap_test, menu);
  return true;
 } 
 
 
 /**
  * 處理呼叫遠端webservice的商業邏輯
  * @param view
  */
 public void processData(View view) {       
  EditText inputNameET = (EditText) findViewById(R.id.et_inputname);
  String inputName = inputNameET.getText().toString();    
  
  SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);  
  request.addProperty("arg0", inputName);
    
  SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
  envelope.setOutputSoapObject(request);
  HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

  try {
   androidHttpTransport.call(SOAP_ACTION, envelope);

   SoapPrimitive resultsRequestSOAP = (SoapPrimitive) envelope.getResponse();
   
   TextView showMeTV = (TextView) findViewById(R.id.tv_showme);
   showMeTV.setText(resultsRequestSOAP.toString());   
   
  } catch (Exception e) {
   e.printStackTrace();
  }  
 }    

}


結語

經過以上簡單的小程式範例介紹之後,相信各位都可以在android平台上設計一個可以向外部伺服務(Server)請求數據服務的功能。

2014年8月30日 星期六

使用DefaultTableModel注入表格資料 - Java視窗程式JTable元件應用


package test.swing.jtable;

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;

public class TestDefaultTableModel extends JFrame {

  public static void main(String[] args) {    
        TestDefaultTableModel frame = new TestDefaultTableModel();
      frame.setVisible(true);
  }

  public TestDefaultTableModel(){    
    setTitle("Test DefaultTableModel for version 1.0.1");    
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100100450500);  //(左邊界,上邊界,宽度,長度)
    JPanel contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(10101010));  //(上,左,下,右)
    setContentPane(contentPane);
    
    //設置Layout的樣式來呈現component之間在Panel上的位置關係
    contentPane.setLayout(new BorderLayout());
    
    //第一種方式: 為table初始宣告一些測試資料  (常用方法1)
    JTable table = new JTable(new Object[][]{
        {"aaa000","aaa001","aaa002"},
        {"bbb000","bbb001","bbb002"},
        {"ccc000","ccc001","ccc002"}}
        new Object[]{"Title A","Title B","Title C"});
    
    //第二種方式: 為table初始宣告一些測試資料  (常用方法2)
    /*Object[][] dataVector = new Object[][]{
        {"xxx000","xxx001","xxx002"},
        {"yyy000","yyy001","yyy002"},
        {"zzz000","zzz001","zzz002"}};
    Object[] columnIdentifiers = new Object[]{"Title X","Title Y","Title Z"};
    DefaultTableModel model = new DefaultTableModel();
    model.setDataVector(dataVector, columnIdentifiers);
    JTable table = new JTable(model);*/      
    
    //第三種方式: 逐一加入每一欄位名稱與該欄位的所有記錄  (為table初始宣告一些測試資料)
    /*DefaultTableModel model = new DefaultTableModel();
    model.addColumn("columnName0", new Object[]{"cn000","cn003","cn006"});
    model.addColumn("columnName1", new Object[]{"cn001","cn004","cn007"});
    model.addColumn("columnName2", new Object[]{"cn002","cn005","cn008"});
    JTable table = new JTable();
    table.setModel(model);*/
    
    //第四種方式: 以Vector逐一加入每一欄位名稱與該欄位的所有記錄  (為table初始宣告一些測試資料)
    /*DefaultTableModel model = new DefaultTableModel();
    Vector cnv = new Vector();
    cnv.add("cln000");
    cnv.add("cln001");
    model.addColumn(new String("columnName0"), cnv);
    cnv = new Vector();
    cnv.add("cln002");
    cnv.add("cln003");
    model.addColumn(new String("columnName1"), cnv);
    cnv = new Vector();
    cnv.add("cln004");
    cnv.add("cln005");
    model.addColumn(new String("columnName2"), cnv);
    JTable table = new JTable(model);*/
    
    //第五種方式: 先加人欄位,後加入資料  (為table初始宣告一些測試資料)
    /*DefaultTableModel model = new DefaultTableModel();
    model.setColumnIdentifiers(new Object[]{"columnName0","columnName1", "columnName2"});
    model.addRow(new Object[]{"coln000","coln001","coln002"});
    model.addRow(new Object[]{"coln003","coln004","coln005"});
    model.addRow(new Object[]{"coln006","coln007","coln008"});
    JTable table = new JTable();
    table.setModel(model);*/
    
    contentPane.add(new JScrollPane(table), BorderLayout.CENTER);    
  }
}

使用Object陣列注入表格資料 - Java視窗程式JTable元件應用


package test.swing.jtable;

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;

public class TestDefaultTableModel extends JFrame {

  public static void main(String[] args) {    
        TestDefaultTableModel frame = new TestDefaultTableModel();
      frame.setVisible(true);
  }

  public TestDefaultTableModel(){    
    setTitle("Test injected some data to JTable.");    
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100100450500);  //(左邊界,上邊界,宽度,長度)
    JPanel contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(10101010));  //(上,左,下,右)
    setContentPane(contentPane);
    
    //設置Layout的樣式來呈現component之間在Panel上的位置關係
    contentPane.setLayout(new BorderLayout());
    
    //以Object陣列為table初始宣告一些測試資料
    JTable table = new JTable(new Object[][]{
        {"aaa000","aaa001","aaa002"},
        {"bbb000","bbb001","bbb002"},
        {"ccc000","ccc001","ccc002"}}
        new Object[]{"Title A","Title B","Title C"});   
    
    contentPane.add(new JScrollPane(table), BorderLayout.CENTER);    
  }
}

2014年8月27日 星期三

善用jQuery的load、get、post的方法

概要


過去只能運用互動式網頁技術向伺服器請求資源服務(如ASP,PHP,JSP等)。隨著AJAX技術的興起,讓我們也可以透過以下jQuery函數向伺服器發起服務請求:

  • Load 取回位於伺服器的檔案資源。

  • Get 向伺服器請求數据服務。

  • Post 提交數据給伺服器處理。


在後面的小節裏,會有每一個函數的使用範例與細部的說明,讓大家能夠很快掌握這些函數的使用要領。

使用jQuery Load函數


在Server端創建一支demo_str.txt的文字檔,作為jQuery Load載入的資料來源,其內容如下: 

<h4>這是一個測試文字檔...</h4>


寫一支load.html,在head把jquery.min.js函數庫載入並增加jquery load的腳本實作的程式碼,呼叫且回傳文字檔的內容到id='jqloadDiv'的div標籤。 

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>使用jQuery Load函數</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#btn1").click(function(){
$("#jqloadDiv").load("demo_str.txt");
});
});
</script>
</head>
<body>

<input type="button" id="btn1" name="btn1" value="執行jQuery Load按鈕" />
<div id="jqloadDiv"></div>

</body>
</html>


操作jQuery Get函數


在Server端建立一支obtval_by_get.php,用作jQuery Get函數的呼叫網頁,該頁程式只有包含了一行簡短的文字內容輸出。


<?php
echo "This is testing data. (by Get func)";
?>


撰寫一支get.html,先在head加入jquery.min.js函數庫,再來增加一段jquery get函數實作的腳本程式碼,呼叫並取回echo輸出的文字串流和連線狀態。


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>使用jQuery Get函數</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#btn1").click(function(){
$.get("obtval_by_get.php",function(data,status){
//alert("資料: " + data + "\n狀態: " + status);
$("#jqDiv").html("資料: " + data + "<br/>狀態: " + status);
});
});
});
</script>
</head>
<body>

<input type="button" id="btn1" name="btn1" value="執行jQuery Get按鈕" />
<div id="jqDiv"></div>

</body>
</html>


運用jQuery Post函數


在Server端建立一支obtval_by_post.php,用來處理由jQuery Post傳遞過來的name和greetings參數,其內容如下:


<?php
if(isset($_POST["name"]) && isset($_POST["greetings"])){
echo $_POST["greetings"].$_POST["name"].". (by Post func)";
}
?>


再寫一支post.html,於head加入jquery.min.js和jquery post函數實作的腳本程式碼,必需附加name與greetings兩個參數值,最後會回傳處理結果和連線狀態。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>使用jQuery Post函數</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#btn1").click(function(){
$.post("obtval_by_post.php",
{
name:"Peter",
greetings:"Hello, "
},
function(data,status){
//alert("資料: " + data + "\n狀態: " + status);
$("#jqDiv").html("資料: " + data + "<br/>狀態: " + status);
});
});
});
</script>
</head>
<body>

<input type="button" id="btn1" name="btn1" value="執行jQuery Post按鈕" />
<div id="jqDiv"></div>

</body>
</html>


總結


閱讀完以上三個簡單的小範例說明之後,讓我們也可以使用jQuery AJAX的技術向伺服器請求資源服務。由於是經過AJAX回傳的結果,不需要刷新頁面,而且還可以動態改變用戶介面(UI)的顯示效果。

jQuery上傳檔案教學

簡介


記得在前面PHP上傳檔案範例文章中,我們已經了解HTML form的檔案上傳的處理方式。在這篇文章我想要向大家介紹jQuery檔案上傳功能(jQuery Upload),它是一個非常簡單、美觀、容易上手使用的JavaScript的函數庫,可以有效的提升網頁開發設計的速度和效率。

jQuery上傳頁面


首先,在head插入一個css和兩個js檔案,

  • uploadfile.min.css  負責處理用戶端上傳畫面的UI呈現

  • jquery.min.js  它是jQuery核心的函數庫

  • jquery.uploadfile.min.js  負責處理檔案上傳的函數庫

再來於body增加一個id='fileuploader'的div標籤,最後於head加入初始化jQuery插件的腳本代碼<script> $(document).ready(... </script>負責呼叫位於Server端的檔案處理邏輯與將回傳結果顯示在畫面上。

完整的index.html程式碼如下:

<html>
<head>
  <title>jQuery Upload Demo.</title>
  <link href="http://hayageek.github.io/jQuery-Upload-File/uploadfile.min.css" rel="stylesheet">
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script src="http://hayageek.github.io/jQuery-Upload-File/jquery.uploadfile.min.js"></script>
  <script>
    $(document).ready(function()
    {
 $("#fileuploader").uploadFile({
 url:"upload.php",
 fileName:"myfile"
 });
    });
  </script>
</head>
<body>

  <div id="fileuploader">Upload</div>

</body>
</html>


檔案處理邏輯


在目前的位置建立uploads目錄,用來存放上傳到伺服器的檔案,接著需要判斷是單一檔案或是多個檔案上傳,分別指派不同的程式邏輯處理。

完整的upload.php程式碼如下:

<?php
$output_dir = "uploads/";
if(isset($_FILES["myfile"]))
{
 $ret = array();
  
 //判斷是單一或多個檔案上傳
 if(!is_array($_FILES["myfile"]["name"])) //單一檔案
 {
    $fileName = $_FILES["myfile"]["name"];
   move_uploaded_file($_FILES["myfile"]["tmp_name"],$output_dir.$fileName);
     $ret[]= $fileName;
 }
 else  //多個檔案
 {
   $fileCount = count($_FILES["myfile"]["name"]);
   for($i=0; $i < $fileCount; $i++)
   {
    $fileName = $_FILES["myfile"]["name"][$i];
  move_uploaded_file($_FILES["myfile"]["tmp_name"][$i],$output_dir.$fileName);
    $ret[]= $fileName;
   }
 
 }
    echo json_encode($ret);
 }
?>


輸出畫面


jq_upload

結論


由於過去一直都有在使用jQuery Upload來開發上傳檔案的程式,因為它是透過AJAX(Asynchronous JavaScript and XML)的方式來處理上傳檔案的資料串流,所以使用者可以依据其特性客製出各式各樣華麗的jQuery Upload使用者介面(UI;User Interface)。

2014年8月26日 星期二

PHP下載檔案實作

概要


如何讓我們能夠以PHP從伺服器下載檔案到用戶端(Client side)的電腦呢?那第一個要映入你的眼簾的必定是HTTP(Hypertext Transfer Protocol)通訊協定的表頭(header),因為PHP就是透過HTTP協定來與用戶端進行資料交換,在下面我們提供兩個下載檔案的作法給各位參考。

建立檔案下載頁面


撰寫一支index_df.html的檔案下載網頁,在這個頁面中需要有兩個下載檔案的超連結,分別指向方法一和方法二的下載檔案的程式代碼。

<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>檔案下載頁面</title>
</head>
<body>
<p><strong>方法一:簡單組合字串變數</strong></p>

<p><a href="download_sf1.php" target="_blank">下載mycontacts.csv檔案</a></p>

<p>&nbsp;</p>

<p><strong>方法二:透過讀取某檔案串流</strong></p>

<p><a href="download_sf2.php" target="_blank">下載mydoc.csv檔案</a></p>
</body>
</html>


下載檔案程式邏輯


方法一:簡單組合字串變數 (download_sf1.php)

<?php
  // 把目前的字串串流輸出到檔案
  header('Content-Description: File Transfer');
  header("Content-type: text/csv; charset=big5");  
  header("Content-disposition: attachment; filename=mycontacts.csv");
  header('Expires: 0');
  header('Cache-Control: must-revalidate');
  header('Pragma: public');   

  // 這裏要注意是\r\n是Windows的換行符號,\n為Unix的換行符號
  $content = "姓名,電話,住址,備註"."\r\n";
  $content .= "N111,tel008,台北,nothing"."\r\n";
  $content .= "N222,tel009,高雄,N/A"."\r\n";

  // 將字串編碼由utf-8轉為big5(非必要)
  $content = iconv("utf-8","big5",$content);
  echo $content;   
?>


方法二:透過讀取某檔案串流 (download_sf2.php)

<?php
  // 把伺服器的檔案串流輸出為指定檔案
  header('Content-Description: File Transfer');
  header("Content-type: text/csv; charset=big5");
  //header('Content-Type: application/octet-stream');
  header("Content-disposition: attachment; filename=mydoc.csv");
  header('Expires: 0');
  header('Cache-Control: must-revalidate');
  header('Pragma: public');   
  
  $filename = "D:\\test_doc.csv";
    
  if (file_exists($filename)) 
  {
   // 讀取某一檔案且輸出檔案串流
   readfile($filename);    
  }  
?>


(下載test_doc.csv檔案連結)

結論


總而言之,各位在進行網頁程式設計時,基礎的HTTP通訊協定的知識必不可少,不僅可以增進自己對用戶端(Client)與伺服器(Server)之間的互動關係之了解,還可以提升程式開發的效率。

PHP上傳檔案範例

前言


一般我們要透過PHP實現上傳檔案的任務,通常需要利用HTML的form元素裏面的enctype屬性設置為multipart/form-data,讓該表單可以傳遞檔案資料型態。後端在以一支PHP程式負責處理表單傳來的檔案數据的更改名檔、放置路徑等等的邏輯處理作業。

選取要上傳的檔案


首先,建立一支index_uf.html程式,讓它包含一個可以上傳檔案的表單(form),於表單內增加input元素type屬性設為file,這樣一來用戶就能從用戶端選取想要上傳的檔案,最後再加入input元素type屬性為submit,讓用戶擁有提交檔案到伺服器的能力。 

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>選取欲上傳的檔案...</title>
</head>
<body>
<form action="upload_file.php" enctype="multipart/form-data" method="post">
<label for="file">檔名:</label>
<input id="file" name="file" type="file" />
<input name="submit" type="submit" value="提交" />
</form>
</body>
</html>


上傳程式邏輯


寫一支upload_file.php程式,開頭先設置utf-8編碼,再來判斷由用戶端傳來的submit按鈕的狀態是否為true,若為true時,於伺服器建立upload目錄、且把暫存檔名更改為用戶指定的檔案名稱(move_uploaded_file函數);反之將連結重新導回選取要上傳檔案畫面。

<?php
// 設定文件utf-8編碼
header("Content-Type:text/html; charset=utf-8");

if(isset($_POST["submit"])){
$sitepath = realpath($_SERVER["DOCUMENT_ROOT"]);
$up_dir = $sitepath . DIRECTORY_SEPARATOR . "upload". DIRECTORY_SEPARATOR;
if(!file_exists($up_dir)){
mkdir($up_dir);
}
$up_file = $up_dir . $_FILES["file"]["name"];
if (file_exists($up_file)) {
echo $_FILES["file"]["name"] . " 已經存在了!";
} else {
move_uploaded_file($_FILES["file"]["tmp_name"], $up_file);
echo "上傳檔案 " . $_FILES["file"]["name"] . "成功!!<br/>";
echo "儲存在: " . $up_file;
}
} else {
header("Location: index_uf.html");
}

?>


總結


上述只是一個簡單的HTML from的檔案上傳的教學文章,除了採用此種上傳檔案方法,你也可以使用jQuery upload或Flash的方式,來完成上傳檔案到伺服器的作業。