2013年11月20日水曜日

ASP.NET 繰り返しコントロール内で2つのDropDownListを連携する。

繰り返しコントロール(GridView,DataList,Repeater)などのItemTemplateにDropDownListを二つ配置し
一つ目のDropDownListの選択値によって二つ目のDropDownListのDataSourceを変更する方法です。

DataListのItemTemplateにDropDownListを二つ配置します。

<asp:DataList ID="DataList1" runat="server">
    <ItemTemplate>
        <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" />
        <asp:DropDownList ID="DropDownList2" runat="server" />
    </ItemTemplate>
</asp:DataList>

DataListのItemCreatedイベントで一つ目のDropDownListにデータを設定し
DropDownListのSelectedIndexChangedイベントを関連付けます。
Private Sub DataList1_ItemCreated(sender As Object, e As DataListItemEventArgs) Handles DataList1.ItemCreated
    Dim ddl1 As DropDownList = DirectCast(e.Item.FindControl("DropDownList1"), DropDownList)
    With ddl1
        .DataValueField = "Cd"
        .DataTextField = "Name"
        .DataSource = GetDropDownList1Data()
        .DataBind()
    End With

    AddHandler ddl1.SelectedIndexChanged, AddressOf ddl1_SelectedIndexChanged
End Sub

一つ目のDropDownListのSelectedIndexChangedイベントでは
一つ目のDropDownListのParentプロパティからDropDownListItemを取得します。
取得したDropDownListItemからFindControlで二つ目のDropDownListはオブジェクトを探します。
Private Sub ddl1_SelectedIndexChanged(sender As Object, e As EventArgs)
    Dim ddl1 As DropDownList = DirectCast(sender, DropDownList)
    Dim ddl1Cd As Integer = CInt(ddl1.SelectedValue)

    Dim item As DataListItem = DirectCast(ddl1.Parent, DataListItem)

    Dim ddl2 As DropDownList = DirectCast(item.FindControl("DropDownList2"), DropDownList)
    With ddl2
        .DataValueField = "Cd"
        .DataTextField = "Name"
        .DataSource = GetDropDownList2Data(ddl1Cd)
        .DataBind()
    End With
End Sub

ASP.NET CustomValidatorでTextが空のTextBoxを検証する

昨晩からドハマりした。
空のテキストボックスをCustomValidatorで検証したい場合はValidateEmptyTextをtrueにしないといけないのね!
知らなかったよー
<asp:TextBox ID="TextBox1" runat="server" />
<asp:CustomValidator ID="CustomValidator1" runat="server" Display="Dynamic" ValidateEmptyText="true"
 ControlToValidate="TextBox1" ErrorMessage="エラーメッセージ"/>

2013年10月9日水曜日

ASP.NET ModalPopupExtenderでDataGridをポップアップ表示し選択した値を元の画面に設定する

ModalPopupExtenderで検索して来られる方が多いようなので、
自分のために、あなたのために書いておきます。

ポップアップ画面にはグリッドが配置されていて、グリッドで選択したデータの値を
呼び出し元のラベルに表示します。
ついでにグリッドのデータは検索で絞り込みができるようにします。

呼び出し元画面には検索ワードを入れるテキストボックスがあり、
ポップアップ表示ボタンを押すと、ポップアップ画面に検索ワードを渡し、ポップアップ表示します。



文章で説明は面倒なのでコード読んでね。

ではまずポップアップ画面から作成です。
ポップアップ画面は使いまわせるようにユーザーコントロールで作成しました。

ModalPopupSample.aspxのデザイナです。
ModalPopupExtenderの設定に注目です。
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="PopUp.ascx.vb" Inherits="WebApplication1.PopUp" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>

<asp:Panel ID="pnlPopup" runat="server" BackColor="#C0C0FF">
    <asp:UpdatePanel ID="updPopup" runat="server" UpdateMode="Conditional">
        <ContentTemplate>

            <asp:Button ID="btnDummy" runat="server" Text="" Style="display: none" />

            <asp:ModalPopupExtender ID="modalPopupExtender" runat="server"
                TargetControlID="btnDummy"
                BackgroundCssClass="modalBackground"
                DropShadow="true"
                PopupControlID="pnlPopup"
                PopupDragHandleControlID="pnlTitle"
                CancelControlID="btnCancel" />

            <asp:Panel ID="pnlTitle" runat="server">
                ここにタイトル
            </asp:Panel>
            <div>
                ここに内容
                <br />
                検索条件:<asp:TextBox ID="txtSearch" runat="server"/><asp:Button ID="btnSearch" runat="server" Text="表示" />

                <asp:GridView ID="gvList" runat="server">
                    <Columns>
                        <asp:TemplateField HeaderText="選択">
                            <ItemTemplate>
                                <asp:LinkButton ID="lnkbtnSelect" runat="server" CommandName="select">選択</asp:LinkButton>
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField HeaderText="列1">
                            <ItemTemplate>
                                <asp:Label ID="lblCol1" runat="server" Text="Label"></asp:Label>
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField HeaderText="列2">
                            <ItemTemplate>
                                <asp:Label ID="lblCol2" runat="server" Text="Label"></asp:Label>
                            </ItemTemplate>
                        </asp:TemplateField>
                    </Columns>
                </asp:GridView>
                <asp:Button ID="btnCancel" runat="server" Text="閉じる" />
            </div>
        </ContentTemplate>
    </asp:UpdatePanel>
</asp:Panel>

ModalPopupSample.aspxのコードです。
Public Class PopUp
    Inherits System.Web.UI.UserControl

    ''' <summary>
    ''' ダイアログを閉じたイベントのイベント引数
    ''' </summary>
    ''' <remarks></remarks>
    Public Class ClosedEventArgs
        Public Property Col1Value As String
        Public Property Col2Value As String
    End Class

    ''' <summary>
    ''' ダイアログを閉じた際のイベント
    ''' </summary>
    ''' <param name="arg"></param>
    ''' <remarks></remarks>
    Public Event DialogClosed(arg As ClosedEventArgs)


    ''' <summary>
    ''' ポップアップウインドウを表示
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Show(sArg As String)
        Me.txtSearch.Text = sArg 
        Me.gvList.Visible = True
        If Not String.IsNullOrEmpty(Me.txtSearch.Text) Then
            SetGridData()
        End If
        Me.updPopup.Update()
        Me.modalPopupExtender.Show()
    End Sub

    ''' <summary>
    ''' 表示ボタンClickイベント
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnSearch_Click(sender As Object, e As EventArgs) Handles btnSearch.Click
        Me.gvList.Visible = True
        SetGridData()
        Me.updPopup.Update()
        Me.modalPopupExtender.Show()
    End Sub

    ''' <summary>
    ''' グリッドのRowDataBoundイベント
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub gvList_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvList.RowDataBound
        If e.Row.RowType <> DataControlRowType.DataRow Then
            Return
        End If

        Dim drv As DataRowView = DirectCast(e.Row.DataItem, DataRowView)
        '選択
        Dim args() As String = New String() {drv.Item("col1").ToString(), drv.Item("col2").ToString()}
        Dim lnkbtnSelect As LinkButton = DirectCast(e.Row.FindControl("lnkbtnSelect"), LinkButton)
        lnkbtnSelect.CommandArgument = String.Join(",", args)
        '列1
        Dim lblCol1 As Label = DirectCast(e.Row.FindControl("lblCol1"), Label)
        lblCol1.Text = drv.Item("col1").ToString()
        '列2
        Dim lblCol2 As Label = DirectCast(e.Row.FindControl("lblCol2"), Label)
        lblCol2.Text = drv.Item("col2").ToString()
    End Sub
    
    ''' <summary>
    ''' グリッドのRowCommandイベント
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub gvList_RowCommand(sender As Object, e As GridViewCommandEventArgs) Handles gvList.RowCommand
        Me.gvList.Visible = False
        Me.modalPopupExtender.Hide()
        Dim args() As String = e.CommandArgument.ToString.Split(","c)
        Dim eventArgs As New ClosedEventArgs
        eventArgs.Col1Value = args(0)
        eventArgs.Col2Value = args(1)
        RaiseEvent DialogClosed(eventArgs)
    End Sub

    ''' <summary>
    ''' グリッドデータ表示
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub SetGridData()
        'データ取得
        Dim sSearch As String = Me.txtSearch.Text
        Dim tbl As New DataTable
        tbl.Columns.Add(New DataColumn("col1", GetType(String)))
        tbl.Columns.Add(New DataColumn("col2", GetType(String)))
        For idx As Integer = 1 To 10
            tbl.Rows.Add(New Object() {idx.ToString, sSearch & idx.ToString})
        Next

        Me.gvList.DataSource = tbl
        Me.gvList.DataBind()
    End Sub


次に呼び出し画面の作成です。

Default.aspxのデザイナです。
ToolkitScriptManagerを配置し、先ほど作成したPopUpユーザーコントロールを配置します。
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="WebApplication1._Default" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<%@ Register Src="~/PopUp.ascx" TagPrefix="uc1" TagName="PopUp" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server"></asp:ToolkitScriptManager>
        <div>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
                <ContentTemplate>
                    検索条件:<asp:TextBox ID="txtSearch" runat="server" /><asp:Button ID="btnShowPopup" runat="server" Text="ポップアップ表示" /><br />
                    列1:<asp:Label ID="lblCol1Value" runat="server"/><br />
                    列2:<asp:Label ID="lblCol2Value" runat="server"/><br />
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
        <uc1:PopUp runat="server" id="PopUp" />
    </form>
</body>
</html>
Default.aspxのコードです。
Public Class _Default
    Inherits System.Web.UI.Page

    Private Sub btnShowPopup_Click(sender As Object, e As EventArgs) Handles btnShowPopup.Click
        'ポップアップ画面の表示
        Me.PopUp.Show(Me.txtSearch.Text)
    End Sub

    Private Sub ModalPopupSample_DialogClosed(arg As PopUp.ClosedEventArgs) Handles PopUp.DialogClosed
        'ポップアップ画面を閉じたとき
        Me.lblCol1Value.Text = arg.Col1Value
        Me.lblCol2Value.Text = arg.Col2Value
        Me.UpdatePanel1.Update()
    End Sub

End Class

説明は以上!!

ASP.NET Global_asaxのApplication_Errorからカスタムエラーページが表示されない

1歳児のお世話をしているとブログを書く時間はないデス。
でも今日はハマったので未来の自分のためにメモです。


Global_asaxのApplication_Errorイベントで
Server.Transferでカスタムエラーページを表示しているのですが
.netのエラーページが表示されてしまい、カスタムエラーページが表示されません。
環境はVS2012,Fw3.5です。
まったく同じコードでもVS2008,Fw2.0ではちゃんと動きます。


こういうのわかりにくいから勘弁してほしい…。

ASP.NETのGlobal_asaxのコードです。
Application_Errorイベントでカスタムエラーページを表示します。
Imports System.Web.SessionState

Public Class Global_asax
    Inherits System.Web.HttpApplication

     Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
        ' エラーの発生時に呼び出されます
        'カスタムエラーページを表示します。
        Server.Transfer("~/CustomError.aspx")
    End Sub

End Class


カスタムエラーページではエラー内容を表示してます。

結論いうと、Loadイベントでエラーを出力した後、Context.ClearError() を呼んであげればちゃんと動きました。
CustomError.aspx
Public Class CustomError
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim ex As Exception
        ex = Server.GetLastError
        If TypeOf ex Is HttpUnhandledException AndAlso ex.InnerException IsNot Nothing Then
            ex = ex.InnerException
        End If

        If ex IsNot Nothing Then
            Me.Label1.Text = ex.GetType.ToString
            Me.Label2.Text = ex.Message
        End If

        Context.ClearError() '<--これが必要。
    End Sub

End Class


web.configです
<system.web>
     <customErrors mode="On"/>
</system.web>

2013年6月1日土曜日

ASP.NET TextBox内でEnterキーを無効にする

TextBox内でEnterキーを押すとポストバックが発生します。
このポストバックを無効にする方法です。

こちらもサンプルは山ほどありますが、自分用にメモしておきます。

JavaScritpでEnterキーを無効にします。
function cancelSubmitOnEnter() {
    if (window.event.keyCode == 13) {
        return false;
    }
}

TextBoxのonKeyPressで先に定義したJavaScriptを呼び出します。

2013年5月31日金曜日

ASP.NET Calendarを使用した日付入力

カレンダーから日付を選択できる日付入力テキストボックスを定義する方法です。
あちこちサンプルはあるんですが、まとまった情報がなかったので自分用にメモしておきます。

Calendarを使用した日付入力

参考サイトはコチラ。
@IT [ASP.NET AJAX]MaskedEditコントロールでテキストボックスに入力可能な値を制限するには?[2.0、3.0、3.5、C#、VB]
@IT [ASP.NET AJAX]Calendarコントロールで日付入力ボックスを定義するには?[2.0のみ、C#、VB]

サンプルとして以下のような画面を作成してみます。
テキストボックスには日付を入力することもカレンダーから日付を選択することもできます。
日付以外を入力するとエラーが表示されます。

まずはDefault.aspxのソースです。
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="Calendar._Default" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style>
        .cal_Theme1 .ajax__calendar_container
        {
            background-color: #e2e2e2;
            border: solid 1px #cccccc;
        }
        .cal_Theme1 .ajax__calendar_header
        {
            background-color: #ffffff;
            margin-bottom: 4px;
        }
        .cal_Theme1 .ajax__calendar_title, .cal_Theme1 .ajax__calendar_next, .cal_Theme1 .ajax__calendar_prev
        {
            color: #004080;
            padding-top: 3px;
        }
        .cal_Theme1 .ajax__calendar_body
        {
            background-color: #e9e9e9;
            border: solid 1px #cccccc;
        }
        .cal_Theme1 .ajax__calendar_dayname
        {
            text-align: center;
            font-weight: bold;
            margin-bottom: 4px;
            margin-top: 2px;
        }
        .cal_Theme1 .ajax__calendar_day
        {
            text-align: center;
        }
        .cal_Theme1 .ajax__calendar_hover .ajax__calendar_day, .cal_Theme1 .ajax__calendar_hover .ajax__calendar_month, .cal_Theme1 .ajax__calendar_hover .ajax__calendar_year, .cal_Theme1 .ajax__calendar_active
        {
            color: #004080;
            font-weight: bold;
            background-color: #ffffff;
        }
        .cal_Theme1 .ajax__calendar_today
        {
            font-weight: bold;
        }
        .cal_Theme1 .ajax__calendar_other, .cal_Theme1 .ajax__calendar_hover .ajax__calendar_today, .cal_Theme1 .ajax__calendar_hover .ajax__calendar_title
        {
            color: #bbbbbb;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server" EnableScriptGlobalization="True" />
    <div>
        <asp:TextBox ID="txtDate" runat="server" Width="100" />
        <asp:MaskedEditExtender ID="meeDate" runat="server" TargetControlID="txtDate" Mask="9999/99/99"
            MaskType="Date" UserDateFormat="YearMonthDay" />
        <asp:ImageButton ID="imgbtnCalendar" runat="server" ImageUrl="~/image/calendar.png"
            OnClientClick="return false;" />
        <asp:CalendarExtender ID="ceDate" runat="server" Format="yyyy/MM/dd" TargetControlID="txtDate"
            PopupButtonID="imgbtnCalendar" CssClass="cal_Theme1" />
        <asp:TextBox ID="TextBox1" runat="server"/>
        <asp:Button ID="btnExec" runat="server" Text="送信" />
        <br />
        <asp:RangeValidator ID="vranDate" runat="server" ControlToValidate="txtDate" Display="Dynamic"
            Type="Date" MinimumValue="1900/01/01" MaximumValue="9999/12/31" ErrorMessage="正しい日付を入力して下さい。"/>
    </div>
    </form>
</body>
</html>

まずはToolkitScriptManager を配置します。
カレンダーを日本語表示するためにEnableScriptGlobalizationプロパティをTrueに設定します。

日付を入力するためのテキストボックスを配置します。(ID:txtDate)

テキストボックスに日付入力の制限をかけるために、MaskedEditExtenderを配置します。(ID:meeDate)
以下のプロパティを設定します。
TargetControlID="txtDate"
Mask="9999/99/99"
MaskType="Date"
UserDateFormat="YearMonthDay"

カレンダーを表示するためのImageButtonを配置します。(ID:imgbtnCalendar)
OnClientClick="return false;"を設定し、サーバーサイドの処理を発生させないようにします。

カレンダーとなるCalendarExtenderを配置します。(ceDate)
以下のプロパティを設定します。
Format="yyyy/MM/dd"
TargetControlID="txtDate"
PopupButtonID="imgbtnCalendar"
CssClass="cal_Theme1"
※CssClassは別に設定しなくてもいいです。
「CalendarExtender css」で検索すると、いろいろ見つかります。

フォーカス移動させるためのTextBox(ID:TextBox1)と送信ボタン(ID:btnExec)を配置します。

日付が正しい形式であるかを検証するためにRangeValidatorを使用します。(ID:vranDate)
以下のプロパティを設定します。
ControlToValidate="txtDate"
Type="Date"
MinimumValue="1900/01/01"
MaximumValue="9999/12/31"
ErrorMessage="正しい日付を入力して下さい。"


以上でカレンダーを使用した日付入力の完成です。

ASP.NET モーダル画面の表示(ModalPopupExtender)

また久しぶりの投稿です。
PHPのお仕事が来るということでPHPの勉強をしていたのですが、来たのはASP.NETのお仕事でした。
ASP.NET久しぶりです。
最後にASP.NETで開発したのが2008年だから、5年ぶりだぁ(;´∀`)
もう記憶がほとんどないです。

ということで、今回の開発で詰まったところを、次回の開発のためにメモしておきます。
次のASP.NETのお仕事はいつかしら・・・

モーダル画面を表示

AjaxControlToolkitのModalPopupExtenderコントロールを使用してモーダル画面を表示する方法はコチラ。
@IT [ASP.NET AJAX]ModalPopupコントロールでモーダル・ウィンドウを生成するには?

サンプルとしてModalPopupExtenderを使用し、以下のようなメッセージダイアログを作成してみます。

まずはimageフォルダに質問、情報、警告、エラー時にメッセージに表示するアイコン画像を保存します。


メッセージダイアログ部分をユーザーコントロールで作成します。
「新しい項目の追加」 > 「Webユーザーコントロール」を選択します。
ファイル名は「Message.ascx」とします。

Message.ascxのソース
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="Message.ascx.vb" Inherits="ModalPopupExtenderSample.Message" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>

<!-- ダミーボタン(非表示) -->
<asp:Button ID="btnDummy" runat="server" Text="Button" Style="display: none" />
<!-- ポップアップ部分 -->
<asp:Panel ID="pnlDialog" runat="server">
    <div class="dialog">
        <div class="title">
            <asp:Label ID="lblTitle" runat="server"></asp:Label>
        </div>
        <div class="content">
            <div class="icon">
                <asp:Image ID="Image1" runat="server" ImageUrl="" /></div>
            <div class="message">
                <asp:Label ID="lblMsg" runat="server"></asp:Label></div>
        </div>
        <br class="clearfloat" />
        <div class="button">
            <asp:Button ID="btnOk" runat="server" Text="OK" />
            <asp:Button ID="btnYes" runat="server" Text="Yes" />
            <asp:Button ID="btnNo" runat="server" Text="No" />
        </div>
    </div>
</asp:Panel>
<!-- ModalPopupExtender -->
<asp:ModalPopupExtender ID="modal" runat="server" TargetControlID="btnDummy" PopupControlID="pnlDialog"
    DropShadow="true" Drag="false" PopupDragHandleControlID="pnlDialog" BackgroundCssClass="modalBackground">
</asp:ModalPopupExtender>
Message.ascxのコード
Public Partial Class Message
    Inherits System.Web.UI.UserControl

    'ダイアログが閉じられたときに発生するイベントです。
    Public Event DialogClosed(ByVal dialogResult As DialogResultType, ByVal source As String, ByVal args() As Object)

    'ダイアログの表示タイプを示す列挙帯です。
    Public Enum StyleType
        Warning
        Information
        [Error]
        Question
    End Enum

    'ダイアログのどのボタンが押されたかを示す列挙帯です。
    Public Enum DialogResultType
        OK
        Yes
        No
    End Enum

    'ダイアログの表示スタイルです。
    Private _Style As StyleType
    'ダイアログのタイトルです。
    Private _sTitle As String
    'ダイアログのメッセージです。
    Private _sMessage As String

    'ダイアログの表示スタイルを取得・設定します。
    Public Property Style() As StyleType
        Get
            Return Me._Style
        End Get
        Set(ByVal value As StyleType)
            Me._Style = value
            'アイコン
            Dim url As String = String.Empty
            Select Case _Style
                Case StyleType.Warning
                    url = "~/image/warning.png"
                Case StyleType.Information
                    url = "~/image/info.png"
                Case StyleType.Error
                    url = "~/image/error.png"
                Case StyleType.Question
                    url = "~/image/question.png"
            End Select
            Me.Image1.ImageUrl = url
            'ボタン
            Select Case _Style
                Case StyleType.Question
                    Me.btnOk.Visible = False
                    Me.btnYes.Visible = True
                    Me.btnNo.Visible = True
                Case Else
                    Me.btnOk.Visible = True
                    Me.btnYes.Visible = False
                    Me.btnNo.Visible = False
            End Select
        End Set
    End Property
    'タイトルを取得・設定します。
    Public Property Title() As String
        Get
            Return Me._sTitle
        End Get
        Set(ByVal value As String)
            Me._sTitle = value
            Me.lblTitle.Text = value
        End Set
    End Property
    'メッセージを取得・設定します。
    Public Property Message() As String
        Get
            Return Me._sMessage
        End Get
        Set(ByVal value As String)
            Me._sMessage = value
            Me.lblMsg.Text = value
        End Set
    End Property
    'ダイアログを呼び出したオブジェクトを取得・設定します。
    Public Property Source() As String
        Get
            Return DirectCast(ViewState("Source"), String)
        End Get
        Set(ByVal value As String)
            ViewState("Source") = value
        End Set
    End Property
    'ダイアログを呼び出した際、任意の引数を取得・設定します。
    Public Property Args() As Object()
        Get
            Return DirectCast(ViewState("args"), Object())
        End Get
        Set(ByVal value As Object())
            ViewState("args") = value
        End Set
    End Property

    'ダイアログを表示します。
    Public Sub Show()
        Me.modal.Show()
    End Sub

    'Yesボタンが押された時の処理です。
    Private Sub btnYes_Command(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs) Handles btnYes.Command
        RaiseEvent DialogClosed(DialogResultType.Yes, Me.Source, Me.Args)
    End Sub
    'Noボタンが押された時の処理です。
    Private Sub btnNo_Command(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs) Handles btnNo.Command
        RaiseEvent DialogClosed(DialogResultType.No, Me.Source, Me.Args)
    End Sub
    'OKボタンが押された時の処理です。
    Private Sub btnOk_Command(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs) Handles btnOk.Command
        RaiseEvent DialogClosed(DialogResultType.OK, Me.Source, Me.Args)
    End Sub

End Class

次にダイアログ画面を呼び出す親画面です。

親画面を「Default.aspx」とします。
ToolkitScriptManager を「form」タグの先頭に配置します。
先ほど作成したMessageユーザーコントロールを配置します。

Default.aspxのソース
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="ModalPopupExtenderSample._Default" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<%@ Register Src="Message.ascx" TagName="Message" TagPrefix="uc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server" />
    <div>
        <asp:Button ID="btnQuestion" runat="server" Text="Question" />
        <asp:Button ID="btnWarning" runat="server" Text="Warning" />
        <asp:Button ID="btnInformation" runat="server" Text="Information" />
        <asp:Button ID="btnError" runat="server" Text="Error" />
        <br />
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        
        <uc1:Message ID="Message1" runat="server" />
    </div>
    </form>
</body>
</html>
Default.aspxのコード
Partial Public Class _Default
    Inherits System.Web.UI.Page

    Private Sub btnQuestion_Command(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs) _
    Handles btnQuestion.Command
        Me.Message1.Style = Message.StyleType.Question
        Me.Message1.Title = "タイトル"
        Me.Message1.Message = "質問メッセージ。よろしいですか?"
        Me.Message1.Source = Me.btnQuestion.ClientID
        Me.Message1.Args = New Object() {"args1", "args2"}
        Me.Message1.Show()
    End Sub
    Private Sub btnWarning_Command(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs) _
    Handles btnWarning.Command
        Me.Message1.Style = Message.StyleType.Warning
        Me.Message1.Title = "タイトル"
        Me.Message1.Message = "警告メッセージ"
        Me.Message1.Source = Me.btnWarning.ClientID
        Me.Message1.Args = New Object() {"args3", "args4"}
        Me.Message1.Show()
    End Sub
    Private Sub btnInformation_Command(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs) _
    Handles btnInformation.Command
        Me.Message1.Style = Message.StyleType.Information
        Me.Message1.Title = "タイトル"
        Me.Message1.Message = "情報メッセージ"
        Me.Message1.Source = Me.btnInformation.ClientID
        Me.Message1.Args = New Object() {"args5", "args6"}
        Me.Message1.Show()
    End Sub
    Private Sub btnError_Command(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs) _
    Handles btnError.Command
        Me.Message1.Style = Message.StyleType.Error
        Me.Message1.Title = "タイトル"
        Me.Message1.Message = "エラーメッセージ"
        Me.Message1.Source = Me.btnError.ClientID
        Me.Message1.Args = New Object() {"args7", "args8"}
        Me.Message1.Show()
    End Sub

    Private Sub Message1_DialogClosed(ByVal dialogResult As Message.DialogResultType, ByVal source As String, ByVal args() As Object) _
    Handles Message1.DialogClosed
        Select Case source
            Case Me.btnQuestion.ClientID
                If dialogResult <> Message.DialogResultType.Yes Then
                    Return
                End If
                Me.Label1.Text = args(0).ToString

            Case Me.btnWarning.ClientID
                If dialogResult <> Message.DialogResultType.OK Then
                    Return
                End If
                Me.Label1.Text = args(0).ToString

            Case Me.btnInformation.ClientID
                If dialogResult <> Message.DialogResultType.OK Then
                    Return
                End If
                Me.Label1.Text = args(0).ToString

            Case Me.btnError.ClientID
                If dialogResult <> Message.DialogResultType.OK Then
                    Return
                End If
                Me.Label1.Text = args(0).ToString

        End Select
    End Sub
End Class
次にスタイルシートです。

「App_Themes」フォルダに「追加」>「ASP.NETフォルダの追加」>「Theme」を選択し、テーマ「theme1」を追加します。
「Theme1」フォルダに「追加」>「新しい項目」より「スタイルシート」を追加します。
ファイル名は「StyleSheet1.css」としました。

Default.aspxにテーマを設定するためweb.configを編集します。
<pages>ノードを探し、以下のように「theme="theme1"」を追加します。
<pages theme="theme1">
「StyleSheet1.css」の中身です。
.dialog { 
    background-color: #F0FFFF;
    width: 400px;
    min-width: 400px;
}
.dialog .title{ 
    background-color: #B0C4DE;
    padding: 5px 10px;
}
.dialog .content 
{
    width: 380px;
    padding: 10px;
    margin-bottom: 10px;
}
.dialog .icon
{
    float: left;
    width: 48px;
    margin-right: 12px;
}
.dialog .message
{
    float: left;
    width: 320px;
 word-break: break-all; /* 表示範囲に合わせて改行 */
    word-wrap: break-word; /* 必要に応じて単語の途中で改行する */
}    
.dialog .button
{
    padding: 10px 0;
    text-align: center;
}
.modalBackground
{
    background-color:black;
    filter:alpha(opacity=75); /* IE:透明度 透明にしちゃうと親画面が操作できてしまうので注意 */
    opacity:0.75;            /* Opera・Safari:透明度 */
    zoom:1;                  /* ModalPopupExtenderでポップアップ表示した際、親画面の背景スタイルがCSSで定義しても生きない(IEのみ)。有効にを適用させるために必要。*/
}

キモになるのは「.modalBackground」です。 「.modalBackground」はユーザーコントロール「Message.ascx」のソースで、ModalPopupExtenderのBackgroundCssClassプロパティに設定しています。
<!-- ModalPopupExtender -->
<asp:ModalPopupExtender ID="modal" runat="server" TargetControlID="btnDummy" PopupControlID="pnlDialog"
    DropShadow="true" Drag="false" PopupDragHandleControlID="pnlDialog" BackgroundCssClass="modalBackground">
</asp:ModalPopupExtender>
メッセージダイアログがポップアップ表示した際、親画面のスタイルを定義します。
まず半透明にしないと、メッセージダイアログを表示した際に親画面が操作できてしまいます。
次にスタイルシートでmodalBackgroundを定義すると、親画面が半透明になりません。
半透明にするためには「zoom:1」とするとよいそうです。
スタイルシートではなくMessage.ascx自体にmodalBackgroundのスタイルを定義するときは「zoom:1」は必要ありません。

今回ハマったのはスタイルシート「.modalBackground」の定義でした(ノД`)・゜・。


追記
ASP.NET ModalPopupExtenderでDataGridをポップアップ表示し選択した値を元の画面に設定する

2013年3月27日水曜日

PHP 例外処理

例外処理

PHP5から例外処理としてtry~catch構文が使えるようになりました。
PHP5.5以前はfinally句は使用できませんが、PHP5.5以降からはfinally句も指定できます。

PHP5.5以前
try {
    例外が発生するかもしれない処理;
} catch (発生するかもしれない例外の種類  変数名) {
    例外発生時の処理;
}
PHP5.5以降
try {
    例外が発生するかもしれない処理;
} catch (発生するかもしれない例外の種類  変数名) {
    例外発生時の処理;
} finally {
    例外が発生しても発生しなくても必ず行う処理。
}

例外を発生させるにはthrowキーワードを使います。
throw new ExceptionまたはExceptionのサブクラス(コンストラクタ引数);


使用例
<?php
//例外をThrowする
class MyClass {
    public function Method1() {
        $this->Method2();
    }
    
    private function Method2() {
        throw new Exception('例外が発生しました。');
    }
}

//例外をcatchする
$obj = new MyClass();
try {
    $obj->Method1();
} catch (Exception $e) {
    print($e->getMessage());
}
?>
実行結果


ExceptionクラスにはgetMessage()メソッドのほかにも以下のようなメソッドがあります。
getMessage例外メッセージ
getCode例外コード
getFile例外を発生したファイル名
getLine例外を発生した行数
getTraceバックトレース(配列)
getTraceAsStringバックトレース(文字列)


例外クラスを継承し独自の例外を作成する

Exceptionクラスまたはそのサブクラスを継承し独自の例外を作成することができます。
//独自例外クラス
class MyException extends Exception {}

//独自例外をThrowする
class MyClass {
    public function Method1() {
        $this->Method2();
    }
    
    private function Method2() {
        throw new MyException('例外が発生しました。');
    }
}

//独自例外をcatchする
$obj = new MyClass();
try {
    $obj->Method1();
} catch (MyException $e) {
    print($e->getMessage());
}


PHPにはExceptionのサブクラスとして以下のような例外が用意されています。
LogicExceptionは開発者が間違ったコードを実装したときに発生させる例外です。
たとえばあるメソッドは引数に数値を想定して作成しているのに、数値に変換できないような文字列が引数に指定されたときはLogicExceptionまたはそのサブクラスをthrowする。
RuntimeExceptionは実行時にしか発生しない例外で通常の例外です。
  • LogicException
    • BadFunctionCallException・・・未定義の関数をコールバックが参照したり、引数を指定しなかったりした場合にスローされる例外です。
      • BadMethodCallException・・・未定義のメソッドをコールバックが参照したり、引数を指定しなかったりした場合にスローされる例外です。
    • DomainException・・・定義したデータドメインに値が従わないときにスローされる例外です。
    • InvalidArgumentException・・・引数が期待値に一致しなかった場合にスローされる例外です。
    • LengthException・・・長さが無効な場合にスローされる例外です。
    • OutOfRangeException・・・無効なインデックスを要求した場合にスローされる例外です。
  • RuntimeException
    • OutOfBoundsException・・・値が有効なキーでなかった場合にスローされる例外です。
    • OverflowException・・・いっぱいになっているコンテナに要素を追加した場合にスローされる例外です。
    • RangeException・・・・プログラムの実行時に範囲エラーが発生したことを示すときにスローされる例外です。
    • UnderflowException・・・空のコンテナ上で無効な操作 (要素の削除など) を試みたときにスローされる例外です。
    • UnexpectedValueException・・・いくつかの値のセットに一致しない値であった際にスローされる例外です。

PHP インターフェース

インターフェース

インターフェースを定義するにはclassキーワードの代わりにinterfaceキーワードを使用します。
インターフェース内のメソッドは抽象メソッドになるので、メソッドの宣言だけを定義し、処理内容は定義しません。
メソッドにはabstractキーワードは付けません。
アクセス修飾子はpublicのみが指定できます。
interface インターフェース名 {
    public function メソッド名($arg1);
}

インターフェースを実装するにはimplementsキーワードを使用します。
複数のインターフェースを実装するにはインターフェース名をカンマで区切ります。
インターフェースを実装したクラスは、インターフェースに定義されているメソッドをすべてオーバーライドする必要があります。
メソッドをオーバーライドしたとき、引数はオーバーライド元のメソッドと同じにするか、省略可能な引数を追加することができます。
class クラス名 implements インターフェース名1, インターフェース名2 {
    public function メソッド名($arg1, $arg2=''){
        処理内容;
    };
}

コンストラクタもインターフェースで定義することができます。
マニュアルには「ひとつのクラスの中で、同じ名前の関数を含む 2 つのインターフェイスを 実装することはできません。あいまいさを解決できなくなるためです。」とありましたが 、実装してもエラーにはならないようです。
<?php
//インターフェース1
interface MyInterface1 {
    public function Method();
    public function Method1($value);
    public function __construct();
}
//インターフェース2
interface MyInterface2 {
    public function Method();
    public function Method2($value);
}
//インターフェースを実装したクラス
class MyClass implements MyInterface1, MyInterface2 {

    public function Method1($value, $str='') { print('Method1</br>'); }
    
    public function Method2($value, $str='') { print('Method2</br>'); }
    
    public function Method(){ print('Method</br>'); }
    
    public function __construct($str=''){}
}
//使用例
$obj = new MyClass();
$obj->Method();
$obj->Method1(1);
$obj->Method2(2);
?>
実行結果


インターフェースを継承し新たなインターフェースを作成することができます。
<?php
//親インターフェース
interface ParentInterface {
    public function Method1();
}
//子インターフェース
interface ChildInterface extends ParentInterface {
    public function Method2();
}
//親インターフェースを実装したクラス
class Class1 implements ParentInterface {

    public function Method1() { print('Method1</br>'); }
    
}
//子インターフェースを実装したクラス
class Class2 implements ChildInterface {

    public function Method1() { print('Method1</br>'); }
    
    public function Method2() { print('Method2</br>'); }
    
}
//使用例
print('-----Class1-----</br>');
$class1 = new Class1();
$class1->Method1();

print('-----Class2-----</br>');
$class2 = new Class2();
$class2->Method1();
$class2->Method2();
?>
実行結果

2013年3月26日火曜日

PHP abstract修飾子

abstract修飾子

abstract修飾子をつけることができるのはクラスとメソッドのみです。

クラスにabstract修飾子をつけると、そのクラスはインスタンス化できません。
abstractクラスにabstractメソッドを含める必要はありません。
<?php
//親クラス(抽象クラス)
abstract class ParentClass {
    public function ParentMethod(){
        print('ParentMethod</br>');
    }
}
//子クラス
class ChildClass extends ParentClass{
}>


//使用例

//ParentClassはインスタンス化できない。
//$parent = new ParentClass();

//ParentClassを継承したChildClassをインスタンス化する。
$child = new ChildClass();
$child->ParentMethod();
?>


メソッドにabstract修飾子をつけると、そのメソッドはサブクラスで必ずオーバーライドしなければなりません。
abstractメソッドを定義しているクラスはabstract修飾子をつけなければなりません。
abstractメソッドはメソッド定義だけを宣言し、処理内容は定義しません。
abstractメソッドをオーバーライドした際のアクセス修飾子は、abstractメソッドで定義した修飾子より同じか緩くする必要があります。
たとえばprotectedで定義したabstractメソッドをオーバーライドするときは、protectedまたはpublicにします。
abstractメソッドをオーバーライドしたとき、引数はabstractメソッドと同じにするか、省略可能な引数を追加することができます。

コンストラクタもabstract修飾子をつけることができます。
PHP5.4以前ではコンストラクタの引数はオーバーライド元のメソッドと違ってもよかったようですが、PHP5.4以降からは引数は同じか、省略可能な引数を追加することができます。
<?php
//親クラス(抽象クラス)
//abstractメソッドを定義しているクラスはabstract修飾子をつける
abstract class ParentClass {
    
    //abstractメソッドはメソッド定義だけを宣言し、処理内容は定義しません。
    protected abstract function AbstractMethod($value);
    
    //コンストラクタもabstractメソッドにすることができます。
    protected abstract function __construct();
}
//子クラス
class ChildClass extends ParentClass {
    //abstractメソッドをオーバーライド
    //アクセス修飾子は、abstractメソッドで定義した修飾子より同じか緩くする
    //引数はabstractメソッドと同じにするか、省略可能な引数を追加することができます
    public function AbstractMethod($value, $str='') {
    }
    
    //コンストラクタをオーバーライド
    //引数はabstractメソッドと同じにするか、省略可能な引数を追加することができます
    public function __construct($str=''){
    }
}
?>

2013年3月25日月曜日

PHP final修飾子

final修飾子

final修飾子をつけることができるのはクラスとメソッドのみです。
クラスにfinal修飾子をつけると、そのクラスは継承できません。
メソッドにfinal修飾子をつけると、そのメソッドは子クラスでオーバーライドできません。
コンストラクタ、アクセッサもメソッドの一種なのでfinal修飾子をつけることがきます。


クラスにfinal修飾子をつけると、そのクラスは継承できません。
<?php
final class ParentClass {
}
//継承するとエラーになります。
class ChildClass extends ParentClass {
}
?>

メソッドにfinal修飾子をつけると、そのメソッドは子クラスでオーバーライドできません。
<?php
class ParentClass {
    public final function Method(){}
}

class ChildClass extends ParentClass {
    //オーバーライドするとエラー
    public function Method() {}
}
?>

コンストラクタにfinal修飾子をつけると、そのコンストラクタは子クラスでオーバーライドできません。
<?php
class ParentClass {
    public final function __construct(){}
}

class ChildClass extends ParentClass {
    //オーバーライドするとエラー
    public function __construct(){}
?>


PHP 継承とオーバーライド

継承

クラスを継承するにはextendsキーワードを使用します。
多重継承はできません。
構文
class 子クラス extends 親クラス {
}


インスタンスメンバをオーバーライド

子クラスでメソッドをオーバーライドしなかった場合、親クラスのメソッドが呼び出されます。
子クラスから親クラスのメンバにアクセスするには「parent::」を利用します。

コンストラクタもメソッドと同じで、
子クラスでコンストラクタを定義しない場合は、親クラスのコンストラクタが継承されます。
子クラスでコンストラクタを定義した場合は親クラスのコンストラクタは自動で呼び出されませんので、親クラスのコンストラクタを明示的に呼び出す必要があります。
親クラスのコンストラクタを呼ばなくてもエラーにはなりません。
<?php
//親クラス
class ParentClass {
    protected $instanceField = 0;
    
    public function __construct($instanceField) {
        print('ParentClass:Construct</br>');
        $this->instanceField = $instanceField;
    }
    
    public function showInstanceField() {
        print($this->instanceField .'</br>');
    }
}
//子クラス1
//親クラスのメソッド、コンストラクタをオーバーライドしない。
class ChildClass1 extends ParentClass {
}

//子クラス2
//親クラスのメソッド、コンストラクタをオーバーライドする。
class ChildClass2 extends ParentClass {
    public function __construct() {
        print('ChildClass2:Construct</br>');
        $this->instanceField = 2;
    }
    
    public function showInstanceField() {
        print('ChildClass2:showInstanceField</br>');
        print($this->instanceField .'</br>');
    }
}
//子クラス3
//親クラスのメソッド、コンストラクタをオーバーライドし、親クラスのメソッドを利用する。
class ChildClass3 extends ParentClass {
    public function __construct() {
        print('ChildClass3:Construct</br>');
        parent::__construct(3);
    }
    
    public function showInstanceField() {
        print('ChildClass3:showInstanceField</br>');
        parent::showInstanceField();
    }
}


//使用例
print('-----子クラス1-----</br>');
$child1 = new ChildClass1(1);
$child1->showInstanceField();

print('-----子クラス2-----</br>');
$child2 = new ChildClass2();
$child2->showInstanceField();

print('-----子クラス3-----</br>');
$child3 = new ChildClass3();
$child3->showInstanceField();
?>
実行結果



スタティックメンバのオーバーロード

スタティックなメンバもインスタンスメンバと同じく、
子クラスでメソッドをオーバーライドしなかった場合、親クラスのメソッドが呼び出されます。
子クラスから親クラスのスタティックメンバにアクセスするには「parent::」を利用します。
子クラスで親クラスのメンバをオーバーライドしなかった場合は「self::」を利用することもできます。
<?php
//親クラス
class ParentClass {
 protected static $staticField = 5;
 
 public function __construct() {
  print('ParentClass:Construct</br>');
 }
 
 public static function showStaticField() {
  print(self::$staticField .'</br>');
 }
}
//子クラス1
//親クラスのスタティックメソッドをオーバーライドしない。
class ChildClass1 extends ParentClass { 
}

//子クラス2
//親クラスのスタティックメソッドをオーバーライド
//スタティック変数はオーバーライドしていないので「parent::」でも「self::」でアクセス可能。
class ChildClass2 extends ParentClass {
 public static function showStaticField() {
  print('ChildClass2:showStaticField' .'</br>');
  print(self::$staticField .'</br>');
 }
}
//子クラス3
//親クラスのスタティック変数、スタティックメソッドをオーバーライド
//「parent::」では親クラスのスタティック変数を参照し、「self::」では自クラスのスタティック変数を参照する。
class ChildClass3 extends ParentClass {
 protected static $staticField = 3;
 
 public static function showStaticField() {
     print('ChildClass3:showStaticField' .'</br>');
  print(self::$staticField .'</br>');
  print(parent::$staticField .'</br>');
 }
}


//使用例
print('-----子クラス1-----</br>');
ChildClass1::showStaticField();

print('-----子クラス2-----</br>');
ChildClass2::showStaticField();

print('-----子クラス3-----</br>');
ChildClass3::showStaticField();

?>
実行結果

2013年3月22日金曜日

PHP 定数

定数宣言

PHPでは定数を宣言する方法として、「define()」関数を使用する方法と、「const」キーワードを使用する方法があります。
どちらを使用しても定数名はすべて大文字で単語の区切りは「_(アンダーバー)」にするのがお約束です。
例:MY_CONST_VALUE
定数に指定できるデータ型はスカラー値(型がboolean, integer, double, string, NULL) のみで配列などは指定できません。


define()関数

構文
define('定数名', 定数値);

使用例
<?php
//定数名「TAX」値「0.05」を定義します。
define('TAX', 0.05);

//定数「TAX」を使用
$price = 1000;
$total = $price + ($price * TAX);
print($total);
?>
define()関数で定義した定数はスコープがグローバルになり、プログラム中のどんな場所でも使用することができます。
あちこちでdefine()関数を使用した定数を定義すると可読性が悪くなります。

define()関数は値の宣言時に演算やメソッドの戻り値が利用できます。
<?php

define('TAX1', 0.05);
//定数値に演算が使える
define('TAX2', 1 * TAX1);
//定数値にメソッドの戻り値を使える
define('TAX3', getTax('2015/01/01'));

function getTax($date) {
    //2014/04/01以前 消費税5%
    //2014/04/01以降 消費税8%
    //2015/10/01以降 消費税10%
    $dt = new DateTime($date);
    $tax = 0;
    if ($dt < new DateTime('2014/04/01')) {
        $tax = 0.05;
    } elseif (($dt >= new DateTime('2014/04/01')) && ($dt < new DateTime('2015/10/01'))) {
        $tax = 0.08;
    } elseif ($dt >= new DateTime('2015/10/01')) {
        $tax = 0.10;
    }
    return $tax;
}

//定数を使用
$price = 1000;

$total1 = $price + ($price * TAX1);
print($total1 .'</br>');

$total2 = $price + ($price * TAX2);
print($total2 .'</br>');

$total3 = $price + ($price * TAX3);
print($total3 .'</br>');

?>
実行結果


constキーワード

クラス内で定数を定義する場合はconstキーワードを使用します。
constキーワードはPHP5から利用可能です。
<?php
class Constant {
    
    const TAX1 = 0.05;
    const TAX2 = 0.08;
    
    public function showTax() {
        print(Constant::TAX1 .'</br>');
        print(self::TAX2 .'</br>');
    }
}
?>
クラスに定義されている定数を使用するサンプルです。
<?php

print(Constant::TAX1 .'</br>');

$obj = new Constant();
print($obj::TAX2 .'</br>');

print($obj->showTax());
?>
クラス内からconstキーワードで定義された定数にアクセスするには「クラス名::定数名」または「self::定数名」とします。
クラス外からアクセスするには「クラス名::定数名」とします。
インスタンス経由でアクセスすることもできます。
$obj = new Constant();
print($obj::TAX2);

constキーワードはdefine()関数と違って、定数の宣言に演算やメソッドの戻り値を利用することはできません。
たとえば以下のような定数定義はエラーになります。
//演算を使う
const TAX = 1 * 0.05;
//ほかの定数を使う
const STR1 = 'aaa';
const STR2 = STR1 .'bbb';
//もちろんほかのメソッドの戻りなんて使えない
const VALE = getHoge();
またconstキーワードにはアクセス修飾子はつけられません。
そのためクラス内だけで有効なクラス外に公開したくない定数などは定義できません。


クラス定数の使いどころ

クラス定数の有効な使い方がわからなかったのでググってみたところ定数をグルーピングする方法がありました。
define()で定義した定数です。
define('WEEKDAY_MON', 1);
define('WEEKDAY_TUE', 2);
define('WEEKDAY_WED', 3);
define('WEEKDAY_THU', 4);
define('WEEKDAY_FRI', 5);
define('WEEKDAY_SAT', 6);
define('WEEKDAY_SUN', 7);

define('RESULT_YES', 1);
define('RESULT_NO', 2);
define('RESULT_CANCEL', 3);
クラス定数で定義すると以下のようになります。
define()で定義するより可読性がいいですが、列挙子のような感じですね。
class Weekday {
    const MON = 1;
    const TUE = 2;
    const WED = 3;
    const THU = 4;
    const FRI = 5;
    const SAT = 6;
    const SUN = 7;
}

class Result {
    const YES = 1;
    const NO = 2;
    const CANCEL = 3;
}


定数を定数値と定数名のペアで管理する

定数は定数値と定数名をペアで管理したい(定数名とは別に別名も管理したい)です。

スタティックメンバを使用した方法

PHPでクラスが使えるならと、いつも使っている方法で書いてみました。
なんだかな・・・といった書き方になってしまいました(´・ω・`)
クラスの変数の初期化にnew演算子が使えない事、スタティック変数を初期化するためのスタティックコンストラクタがないことが不便ですね・・・
cd; }
    public function get_name() { return $this->name; }
    public function get_aliasName() { return $this->aliasName; }
    
    protected function __construct($cd, $name, $aliasName = '') {
        $this->cd = $cd;
        $this->name = $name;
        $this->aliasName = $aliasName;
    }
}
//曜日定数クラス
final class Weekday extends ConstBase {
    protected function __construct($cd, $name, $aliasName = '') {
        parent::__construct($cd, $name, $aliasName);
    }

    private static $MON;
    private static $TUE;
    private static $WED;
    private static $THU;
    private static $FRI;
    private static $SAT;
    private static $SUN;

    public static function MON(){
        if (is_null(self::$MON)) { self::$MON = new Weekday(1,'月曜日','月'); }
        return self::$MON;
    }
    public static function TUE(){
        if (is_null(self::$TUE)) { self::$TUE = new Weekday(2,'火曜日','火'); }
        return self::$TUE;
    }
    public static function WED(){
        if (is_null(self::$WED)) { self::$WED = new Weekday(3,'水曜日','水'); }
        return self::$WED;
    }
    public static function THU(){
        if (is_null(self::$THU)) { self::$THU = new Weekday(4,'木曜日','木'); }
        return self::$THU;
    }
    public static function FRI(){
        if (is_null(self::$FRI)) { self::$FRI = new Weekday(5,'金曜日','金'); }
        return self::$FRI;
    }
    public static function SAT(){
        if (is_null(self::$SAT)) { self::$SAT = new Weekday(6,'土曜日','土'); }
        return self::$SAT;
    }
    public static function SUN(){
        if (is_null(self::$SUN)) { self::$SUN = new Weekday(7,'日曜日','日'); }
        return self::$SUN;
    }
}
//使用例
print(Weekday::MON()->get_cd() .':' .Weekday::MON()->get_name());
?>

連想配列を使用した方法

クラスの変数に配列を指定できるので、連想配列を使ってもうちょっとシンプルにしてみました。
<?php
define('CD','Cd');
define('NAME','Name');
define('ALIAS_NAME','AliasName');

//曜日定数クラス
final class Weekday {
  public static $MON = array(CD=>1, NAME=>'月曜日', ALIAS_NAME=>'月');
  public static $TUE = array(CD=>2, NAME=>'火曜日', ALIAS_NAME=>'火');
  public static $WED = array(CD=>3, NAME=>'水曜日', ALIAS_NAME=>'水');
  public static $THU = array(CD=>4, NAME=>'木曜日', ALIAS_NAME=>'木');
  public static $FRI = array(CD=>5, NAME=>'金曜日', ALIAS_NAME=>'金');
  public static $SAT = array(CD=>6, NAME=>'土曜日', ALIAS_NAME=>'土');
  public static $SUN = array(CD=>7, NAME=>'日曜日', ALIAS_NAME=>'日');
  
  public static function getItems(){
   return array(self::$MON, self::$TUE, self::$WED, self::$THU, self::$FRI, self::$SAT, self::$SUN);
  }

}
//使用例
print (Weekday::$MON[CD] .'</br>');
print (Weekday::$TUE[NAME] .'</br>');
print (Weekday::$WED[ALIAS_NAME] .'</br>');

foreach (Weekday::getItems() as $item) {
 print( $item[CD] .':' .$item[NAME] .'</br>' );
}

?>


定数で値と名称をペアで管理することって普通にあると思うんですけど、PHPでは一般的にどうするのでしょう?
PHPerの人だれか教えてm(´・ω・`)m

2013年3月20日水曜日

PHP クラス定義 ~静的メンバ(static)~

クラス定義

スタティックメンバのサンプルとしてシングルトンパターンのクラスを定義しました。
シングルトンパターンとはクラスのインスタンスが1つしか生成されないことを保証するパターンです。
コンストラクタをprivateにし、外部からインスタンス化できないようにします。
自身のインスタンスを保持するstatic変数とその変数のゲッターをstaticで定義します。
<?php
class User {

    //スタティック変数
    private static $instance;
    
    //スタティックアクセサメソッド
    public static function get_instance() {
        if (is_null(self::$instance)) {
            self::$instance = new User();
        }
        return self::$instance;
    }
    
    
    //スタティックメソッド
    public static function createDefaultuser() {
        $defUser = self::get_instance();
        $defUser->lastName = "山本";
        $defUser->firstName = "一郎";
    }
    
    public static function changeUser(){
        $defUser = User::get_instance();
        $defUser->lastName = "山本";
        $defUser->firstName = "二郎";
    }

    
    //インスタンス変数
    private $lastName;
    private $firstName;
    
    //アクセサメソッド
    public function get_lastName() { return $this->lastName; }
    public function set_lastName($lastName) { $this->lastName = $lastName; }

    public function get_firstName() { return $this->firstName; }
    public function set_firstName($firstName) { $this->firstName = $firstName; }
    
    //コンストラクタ
    private function __construct( $lastName='名無しの', $firstName='ゴンベイ') {
        $this->lastName = $lastName;
        $this->firstName = $firstName;
    }
    
    //インスタンスメソッド
    public function showName(){
        print("私の名前は「" .$this->createName() ."」です。>/br<");
    }
    
    private function createName(){
        return " $this->lastName   $this->firstName";
    }
}
?>
クラスを使用するサンプル
<?php
User::get_instance()->showName();

User::createDefaultUser();
$user = User::get_instance();
$user->showName();

$user::changeUser();
$user->showName();
?>
実行結果


スタティック変数

初期化はリテラルあるいは定数でのみ可能です。 式で初期化することはできません。
つまり、スタティック変数を整数値や配列で初期化することはできますが、 他の変数の値や関数の返り値、オブジェクトなどで初期化することはできません。
private static $val = new Hoge(); はエラーになります。
インスタンス変数にオブジェクトを持たせたい場合、コンストラクタで初期化すればよいですが、
PHPではスタティックなコンストラクタはサポートされていないので、スタティック変数にオブジェクトを持たせたい場合は工夫が必要です。
う~ん。ちょっと不便だ。


クラス内から自クラスに定義されているスタティックメンバにアクセスする

クラス内からクラスに定義されているスタティックなメンバにアクセスするためには「クラス名::スタティックメンバ名」または「self::スタティックメンバ名」とします。
スタティック変数にアクセスするには「User::$instance」または「self::$instance」とします。(スタティック変数に「$」はいります。)
アクセッサやスタティックメソッドにアクセスするのも同様に「User::get_instance()」または「self::get_instance()」とします。


クラス外からクラスに定義されているスタティックメンバにアクセスする

クラス外からクラスに定義されているスタティックなメンバにアクセスするためには「クラス名::スタティックメンバ名」とします。
Userクラスに定義されたスタティックメソッド「createDefaultuser()」にアクセスするには
User::createDefaultuser()
とします。
インスタンス経由でもスタティックなメンバにアクセスできます。
$user = new User();
$user::changeUser();
$user->showName();

PHP クラス定義 ~基本~

クラス定義

クラスは基本的に1クラス1ファイルで定義し、ファイル名は「クラス名.class.php」とするのが一般的です。
以下に定義したUserクラスの場合、ファイル名は「User.class.php」となります。
クラス名はPascal形式(大文字で始め単語の区切りも大文字にする)です。

<?php
class User {

    //インスタンス変数
    private $lastName;
    private $firstName;
    
    //アクセサメソッド
    public function get_lastName() { return $this->lastName; }
    public function set_lastName($lastName) { $this->lastName = $lastName; }

    public function get_firstName() { return $this->firstName; }
    public function set_firstName($firstName) { $this->firstName = $firstName; }
    
    //コンストラクタ
    public function __construct( $lastName='名無しの', $firstName='ゴンベイ') {
        $this->lastName = $lastName;
        $this->firstName = $firstName;
    }
        
    //インスタンスメソッド
    public function showName(){
        print('私の名前は「' .$this->createName() .'」です。</br>');
    }
    
    private function createName(){
        return " $this->lastName   $this->firstName";
    }
    
}
?>
クラスを使用するサンプル
<?php
print('■User1</br>');
$user1 = new User();
$user1->showName();

print('■User2</br>');
$user2 = new User();
$user2->set_lastName('田中');
$user2->set_firstName('太郎');
$user2->showName();

print('■User3</br>');
$user3 = new User('山田','花子');
$user3->showName();
$user3->showFirstName();

?>
実行結果


アクセス修飾子

PHPで利用可能な修飾子は以下の3つ
  • public ・・・ どこからでもアクセス可能
  • protected ・・・ 現在のクラスとサブクラスでのみアクセス可能
  • private ・・・ 現在のクラス内部でのみアクセス可能
アクセス修飾子を省略した場合、publicとなる。


インスタンス変数

変数と同じく、変数の頭に「$」をつけ、camel形式(小文字ではじめ単語の区切りは大文字)で定義します。
初期化はリテラルあるいは定数でのみ可能です。 式で初期化することはできません。
つまり、インスタンス変数を整数値や配列で初期化することはできますが、 他の変数の値や関数の返り値、オブジェクトなどで初期化することはできません。
private $val = new Hoge(); はエラーになります。
インスタンス変数にインスタンスオブジェクトなどを持たせたい場合、コンストラクタで初期化することになります。


アクセサメソッド

セッターは「set_インスタンス変数名」、ゲッターは「get_インスタンス変数名」と命名します。


コンストラクタ

PHP4はクラス名と同名のメソッドをコンストラクタとしていました。
PHP5からは「__construct」とう名称でコンストラクタを定義するようにします。
もし「クラス名と同名のコンストラクタ」と「__construct」が存在する場合は「__construct」が優先されます。
コンストラクタは引数を指定することができますが、PHPではオーバーロード(同名のメソッドで引数が違うメソッドを複数定義すること)ができません。


デストラクタ

PHP5から使用でき「__destruct」という名称で定義します。


インスタンスメソッド

camel形式(小文字ではじめ単語の区切りを大文字にする)で定義します。


クラス内から自クラスに定義されているメンバにアクセスする

クラス内から自クラスに定義されているインスタンス変数やアクセッサ、インスタンスメソッドにアクセスするためには「$this」キーワードを使用します。
インスタンス変数にアクセスするには「$this->firstName」とします。(インスタンス変数に「$」はいりません。)
アクセッサやインスタンスメソッドにアクセスするのも同様に「$this->get_firstNmae()」とします。

※余談ですが・・・
文字列型の変数を扱う場合、値をダブルクォテーションで囲むと文字列に含まれる変数を展開してくれますが
$str = "私の名前は「$this->lastNmae $this->firstName」です。"
とすればインスタンス変数は展開されます。
でも
$str = "私の名前は「$this->get_lastNmae() $this->get_firstName()」です。"
としても、メソッドやアクセッサは展開されません。
あたりまえですけど、ちょっとできるかな~と思ってしまいました。


クラスをインスタンス化し使用する

クラスをインスタンス化するには
$変数名 = new クラス名([引数1,引数2,・・・]);
とします。

インスタンス化したメソッドなどにアクセスするには
[戻り値 = ] $変数名->メソッド名([引数1,引数2,・・・]);
とします。

2013年3月19日火曜日

PHP 関数

関数

[戻り値=] 関数名( [引数1, 引数2, ・・・])
関数名の命名規約は、すべて小文字で単語の間にアンダースコアを使用するスタイル「do_something()」と、camel形式「doSomething()」があるようです。

関数や静的メソッド、インスタンスメソッドのすべてをcamel形式で記述する方式や
インスタンスメソッドの場合はcamel形式を使用し、静的メソッドや関数はアンダースコア形式を使用するよう方式などあるようです。

私は、特に決まりがないならすべてcamel形式で書いていこうと思います。


戻り値のない関数

以下の例では関数「showString()」は、引数「$str」で指定した文字列を、引数「$count」で指定した回数だけ出力します。
<?php

function showString($str, $count) {
    for ($i=1; $i<=$count; $i++) {
        print("$str </br>");
    }
}

showString('やっほ~', 3);
?>
実行結果


戻り値のある関数

以下の例では関数「createString()」は、引数「$str」で指定した文字列を、引数「$count」で指定した回数だけ繰り返した文字列を返します。
<?php

function createString($str, $count) {
    $ret = '';
    for ($i=1; $i<=$count; $i++) {
        $ret .= "$str </br>";
    }
    return $ret;
}

$ret = createString('やっほ~', 3);
print($ret);

?>
実行結果


関数の引数を省略する

引数にデフォルト値を明記すると、その引数は省略可能になります。
省略可能な引数は、値の設定が必要な引数の後方に配置します。
以下の例では関数「showString()」は、引数「$str」で指定した文字列を、引数「$count」で指定した回数だけ出力します。
引数「$count」を省略した場合は5回出力します。
<?php

function showString($str, $count=5) {
    for ($i=1; $i<=$count; $i++) {
        print("$str </br>");
    }
}

showString('やっほ~');
?>
実行結果


2013年3月18日月曜日

PHP 繰り返し処理

for命令

for (初期化式; 条件式; 変化式){
    処理1;
}
<?php
for ($i=1; $i < 10; $i++ ) {
 print("ループ: $i <br/>");
}
?>
実行結果


foreach命令

foreacg (配列 as 変数) {
    処理1;
}

以下は配列の中身を表示するサンプルです。
<?php
$ary = array('aaa', 'bbb', 'ccc', 'ddd', 'eee');
foreach ($ary as $value) {
 print($value .'<br/>');
}
?>
実行結果



以下は連想配列の中身を表示するサンプルです。
<?php
$ary['key1'] = 'aaa';   
$ary['key2'] = 'bbb';   
$ary['key3'] = 'ccc'; 

print('■キーを出力<br/>');
foreach ($ary as $key){
 print($key .'<br/>');
}

print('■値を出力<br/>');
foreach($ary as $value) {
 print($value .'<br/>');
}

print('■キーと値を出力<br/>');
foreach($ary as $key=>$value) {
 print("キー: $key 、値: $value" .'<br/>');
}
?>
実行結果


while命令

while (条件式) {
    処理1;
}
<?php
$i = 1;
while ($i < 10 ) {
 print("ループ: $i <br/>");
    $i++;
}
?>
実行結果


do…while命令

do {
    処理1;
while (条件式);
<?php
$i = 1;
do {
 print("ループ: $i <br/>");
    $i++;
} while ($i < 10)
?>
実行結果


continue命令とbreak命令

ループをスキップするcontinue命令と、ループを中断するbreak命令ですが
オプションの引数で階層を指定することができ、ネストされたループのどのループをスキップまたは中断するかを指定できます。
引数を省略すると1が指定されたことになります。

以下の例だとネストされたループの内側をスキップします。
<?php
for ($i=1; $i<5; $i++ ) {
    for ($j=1; $j<10; $j++) {
        //$jが偶数であればスキップ、内側のループをスキップ
        if ($j % 2 == 0) {
            continue;
        }
        print("$i - $j <br/>");
    }
}
?>
実行結果


以下の例だとネストされたループの外側をスキップします。
<?php
for ($i=1; $i<5; $i++ ) {
    for ($j=1; $j<10; $j++) {
        //$jが偶数であればスキップ、外側のループをスキップ
        if ($j % 2 == 0) {
            continue 2;
        }
        print("$i - $j <br/>");
    }
}
?>
実行結果

2013年3月15日金曜日

PHP 条件分岐

if命令

if (条件) {
    処理1;
} elseif (条件) {
    処理2;
} else {
    処理3; 
}

<?php
$var = 8;

if ($var < 5) {
    print('$varは5以下です。');
} elseif ($var < 10) {
    print('$varは10以下です。');
} else {
    print('$varはいずれにも合致しません。');
}
?>
実行結果


switch命令

switch (式){
    case 値1:
        処理1;
        break;
    case 値2:
        処理2;
        break;
    case 値3:
        処理3;
        break;
    default:
        処理4;
}
<?php
$var = 'B';

switch ($var) {
    case 'A' :
        print('大変よくできました。');
        break;
    case 'B' :
        print('良くできました。');
        break;
    case 'C' :
        print('がんばりましょう');
        break;
    default :
        print('ランク外です。');
        break;
}
?>
実行結果

PHP 演算子

代数演算子

+$x + $y$xと$yの和
-$x - $y$xと$yの差
*$x * $y$xと$yの積
/$x / $y$xと$yの商
%$x % $y$xと$yで割った余り
++$x++$xの値に1を足した後$xを返す
++++$x$xを返した後に$xの値に1を足す
--$x--$xの値に1を引いた後$xを返す
----$x$xを返した後に$xの値に1を引く


代入演算子

=$x = 10$xに10を代入する
+=$x += 10$x = $x + 10と同じ
-=$x -= 10$x = $x - 10と同じ
*=$x *= 10$x = $x * 10と同じ
/=$x /= 10$x = $x / 10と同じ
%=$x %= 10$x = $x % 10と同じ
.=$x .= 'A'$x = $x . 'A'と同じ


比較演算子

==$x == $y$xと$yが等しい場合にTRUEを返す
===$x === $y$xと$yが等しく、かつ同じデータ型の場合にTRUEを返す
!=$x != $y$xと$yが等しくない場合にTRUEを返す
!==$x !== $y$xと$yが等しくなく、または同じデータ型でない場合にTRUEを返す
<$x < 10$xが10より小さい場合にTRUEを返す
>$x > 10$xが10より大きい場合にTRUEを返す
<=$x <= 10$xが10以下の場合にTRUEを返す
>=$x >= 10$xが10以上の場合にTRUEを返す
?$x > 10 ? 'OK' : 'NG'(条件式)?(式1):(式2) 条件式がTRUEの場合は式1をFALSEの場合は式2を返す

「==」は型変換を行って値が等しいかどうかをチェックします。
「===」は型変換を行わないので「==」で比較するよりパフォーマンスに優れます。
下の例だと「==」は文字列である$xが 数値に変換され、 数値としての比較を行います。
<?php
    $x = '10';
    $y = 10;
    print( ($x == $y) ? 'TRUE' : 'FALSE'); //TRUEが出力される
    print('
'); print( ($x === $y) ? 'TRUE' : 'FALSE'); //FALSEが出力される ?>


論理演算子

&&$x == 10 && $y == 10$xと$yがともにTRUEの場合にTRUEを返す
||$x == 10 || $y == 10$xまたは$yのいずれかがTRUEの場合TRUEを返す
xor$x == 10 xor $y == 10$xか$yかの どちらかがTRUEで、$xと$yがどちらもTRUEでない場合にTRUEを返す
!!$flag$flagがTRUEでない場合TRUEを返す


その他の演算子

.'aaa'.$memo文字列連結。
@@print(1/0)式の先頭に指定することでエラーメッセージを非表示にする

「@」演算子はエラー制御演算子ともいい、式の前に付けた場合、 その式により生成されたエラーメッセージは無視されます。
以下の例だと0で除算すると「Warning: Division by zero in xxx.php on line X」とエラーが発生します。
<?php
    print(1/0); 
?>
しかしprint命令の先頭に「@」をつけるとエラーメッセージが抑制され表示されなくなります。
<?php
    @print(1/0); 
?>

ちょっと愚痴

ドットネットの仕事中
次はJavaの仕事「とる」からJavaの勉強してと言われ
Javaの勉強するが仕事なし。

あいかわらずドットネットの仕事中
Androidで開発するからAndroidの勉強してと言われ
Androidの勉強をしても仕事なし。

やっぱりAndroidじゃなくてiPhoneで開発しようかなと言われ
これは聞き流すことにした。

やっぱりドットネットの仕事ばっかりで
忘れたころにJavaの仕事がやってきた。
おぼえてねぇよ・・・と思ったら少しは覚えてた。ヨカッタ

やっぱりドットネットの仕事してるけど
PHPの仕事ありそうだから勉強しといてと言われ
PHPの勉強している自分

なんだかなぁ

2013年3月12日火曜日

PHP 配列

配列(インデックスを指定しない)

インデックスを指定しないで配列を作成する方法です。
<?php
$array1 = array('aaa', 'bbb', 'ccc');
print_r($array1);
?>
または
<?php
$array1[] = 'aaa';
$array1[] = 'bbb';
$array1[] = 'ccc';
print_r($array1);
?>
実行結果


配列(インデックスを指定する)

インデックスを指定して配列を作成する方法です。
<?php
$array1 = array(0=>'aaa', 1=>'bbb', 2=>'ccc');
print_r($array1);
?>
または
<?php
$array1[0] = 'aaa';
$array1[1] = 'bbb';
$array1[2] = 'ccc';
print_r($array1);
?>
実行結果


連想配列

キーを指定して配列を作成する方法です。
<?php
$array1 = array('key1'=>'aaa', 'key2'=>'bbb', 'key3'=>'ccc');
print_r($array1);
?>
または
<?php
$array1['key1'] = 'aaa';
$array1['key2'] = 'bbb';
$array1['key3'] = 'ccc';
print_r($array1);
?>
実行結果


多次元配列

<?php
//array()を使用する方法
$array1 = array(
   array('山田', 'Yamada@mail.com'),
   array('田中', 'Tanaka@mail.com'),
   array('加藤', 'Kato@mail.com')
   );

print($array1[1][0]); //「田中」が出力
print('<br/>');
print($array1[2][1]); //「Kato@mail.com」が出力
print('<br/>');


//インデックスを指定する方法
$array2[0][0] = '山田';
$array2[0][1] = 'Yamada@mail.com';
$array2[1][0] = '田中';
$array2[1][1] = 'Tanaka@mail.com';
$array2[2][0] = '加藤';
$array2[2][1] = 'Kato@mail.com';

print($array2[1][0]); //「田中」が出力
print('<br/>');
print($array2[2][1]); //「Kato@mail.com」が出力
print('<br/>');


//キーを指定する方法
$array3[0]['name'] = '山田';
$array3[0]['mail'] = 'Yamada@mail.com';
$array3[1]['name'] = '田中';
$array3[1]['mail'] = 'Tanaka@mail.com';
$array3[2]['name'] = '加藤';
$array3[2]['mail'] = 'Kato@mail.com';

print($array3[1]['name']); //「田中」が出力
print('<br/>');
print($array3[2]['mail']); //「Kato@mail.com」が出力
print('<br/>');


//他にも
$aryName = array('山田', '田中', '加藤');
$aryMail = array('Yamada@mail.com', 'Tanaka@mail.com', 'Kato@mail.com');
$array4 = array($aryName, $aryMail);

print($array2[1][0]); //「田中」が出力
print('<br/>');
print($array2[2][1]); //「Kato@mail.com」が出力
print('<br/>');

?>
実行結果


配列の初期化

<?php
$array1 = array();
?>


配列の変更・追加

<?php
$array1[0] = 'aaa';
$array1[1] = 'bbb';
$array1[3] = 'ccc';

//変更
$array[0] = 'aaa_upd';

//追加
$array1[] = 'ddd'; //配列の途中に空き要素があっても、配列の最後(要素4)に追加される

print_r($array1);
?>


実行結果

2013年3月11日月曜日

PHP 変数

変数

PHPは変数の宣言を必要としません。
スクリプト内で変数が初めて使用されたタイミングでメモリに領域が確保されます。

変数は「$」で始まること。
変数名の大文字、小文字は区別されます。
変数の型は基本的に意識しません。
変数の命名規約はcamel形式(小文字で開始し単語の区切りを大文字にする。例:$intValue)が一般的なようです。
<?php
    $data = 'Hello';
    print($data);
    $data = 1234;
    print($data);
?>


文字列型の変数

文字列型の変数を扱う場合、値をダブルクォテーションまたはシングルクォテーションで囲む必要があります。
使い分けは文字列に含まれる変数をを展開するかどうかで区別します。
<?php
$value = 'Hello';
//シングルクォテーションは変数が展開されない
$str1 = '$value World!<br/>';
print($str1);
//ダブルクォテーションは変数が展開される
$str2 = "$value World!<br/>";
print($str2);
?>
実行結果



データ型のキャスト

PHPはデータ型にうるさくない言語ですが、キャストが必要な場合は下記のように行います。
<?php
//整数型から文字列型へのキャスト
$intvalue = 123;
$strvalue = (string)$intvalue;
print($strvalue);
?>
キャストで指定可能なデータ型
(int), (integer) - 整数へのキャスト
(bool), (boolean) - 論理値へのキャスト
(float), (double), (real) - float へのキャスト
(string) - 文字列へのキャスト
(binary) - バイナリ文字列へのキャスト (PHP 6)
(array) - 配列へのキャスト
(object) - オブジェクトへのキャスト
(unset) - NULL へのキャスト (PHP 5)

PHP 基本

PHPとは

PHPとはサーバーサイドスクリプト言語です。
HTML埋め込み型のスクリプト言語で、コンパイル不要のインタープリター言語です。


スクリプティングデリミタ

PHPはHTMLコードの中に「<?php ~ ?>」というブロックを記述し、そのブロック内にPHPの命令を記述します。
<?php

?>


コメント

1行コメントは「//」
ブロックコメントは「/* ~ */」
<?php
    //1行コメント

    /*
    ブロックコメント
    */
?>


PHPではそれぞれの式は「;(セミコロン)」で区切られます。
<?php
    print('Hello World!');

    print
    ('Hello World!');
 
?>

PHP 環境作成

Apacheの入手

http://httpd.apache.org/よりApacheをダウンロードします。
インストーラ付の2.2.22をダウンロードしました。

「Download!」より「From a Mirror」を選択します。


「archive download site」を選択します。


「binaries/」を選択します。


「win32/」を選択します。


「httpd-2.2.22-win32-x86-openssl-0.9.8t.msi」を選択します。



Apacheのインストール

先ほどダウンロードした「httpd-2.2.22-win32-x86-openssl-0.9.8t.msi」を実行しインストールを開始します。

「Next」をクリックします。


「I accept the terms int the license agreement」を選択し、「Next」をクリックします。


「Next」をクリックします。


Network Domain(サーバのドメイン名) : localhost
Server Name(wwwサーバ名) : localhost
Administrator's Email Address(管理者のメールアドレス) : aaa@bbb.com
を設定し、「for All Users, on Port80, as a Service」を選択し、「Next」をクリックします。


「Typical」を選択し、、「Next」をクリックします。


インストールフォルダを設定します。
※今回は「C:\Program Files2\Apache2.2」にインストールするので、Changeボタンからインストールフォルダを変更し、「Next」をクリックします。



「Install」をクリック します。


「Finish」をクリック します。


インストールが完了したらタスクバーに「Apache HTTP Server Monitor」が表示されます。
赤色の場合はApacheは停止しています。


このアイコンを右クリックし「Open Apache Monitor」を選択します。
Apache Service Monitorが表示されるので、「Start」ボタンをクリックし、Apacheを起動します。


緑色の場合はApacheは起動しています。


ブラウザで「http://localhost/」にアクセスし下記のようなページが表示されることを確認します。



PHPの入手

http://php.net/downloads.phpよりPHPをダウンロードします。
2013/03/01時点での最新は5.4.12

Windowsで使用するので「Windows 5.4.12 binaries and source」を選択します。


「VC9 x86 Thread Safe」の「Zip」を選択します。


ダウンロードした「php-5.4.12-Win32-VC9-x86.zip」を解凍します。
解凍したフォルダをC:\Program Files2に配置しフォルダ名を「php-5.4.12」にリネームします。

C:\Program Files2\php-5.4.12フォルダ内にある「 php.ini-development」ファイルを同フォルダにコピーし、「php.ini」にリネームします。


PHPとApacheとの連携を行う

C:\Program Files2\Apache2.2\conf\httpd.confをテキストエディタで開きます。
最終行に以下の3行を追加します。
PHPIniDir "c:/Program Files2/php-5.4.12"
LoadModule php5_module "c:/Program Files2/php-5.4.12/php5apache2_2.dll"
AddType application/x-httpd-php .php



動作確認

C:\Program Files2\Apache2.2\htdocsフォルダに「phpinfo.php」ファイルを作成します。
ファイルの内容は次のコードを記載します。
<?php phpinfo(); ?>

Apacheを再起動し、ブラウザで「http://localhost/phpinfo.php」にアクセスします。
下記のようなページが表示されたら設定は成功です。