Phalanger 공식 웹 사이트에서 따로 소개된 적은 없지만, Phalanger와 웹 매트릭스는 아주 이상적인 궁합을 보여주고 있으며 Phalanger가 보여주고자 하는 모습을 가감없이 완벽하게 보여줍니다. 이 아티클을 다 읽고 나면 지금 말하는 것이 어떤 의미인지 알게 될 것입니다.

Phalanger 설치하기

우선 컴퓨터에 Phalanger를 설치해야 합니다. 이전 아티클에서 이야기한대로 Phalanger는 .NET Framework 4.0을 필요로 합니다. 그리고 지금 우리가 실습하려는 WebMatrix도 설치해야 하는데, 결론적으로 지금 이야기하는 도구와 프레임워크들은 한 번에 Microsoft /web 홈페이지에서 제공하는 Web Platform Installer를 이용하여 한 번에 설치할 수 있습니다. http://www.microsoft.com/web 에서 WPI를 설치하고 WebMatrix와 .NET Framework 4.0을 선택하여 설치를 진행하도록 합니다. Phalanger를 설명하는 과정에서는 필요없지만, C#이나 VB.NET을 같이 사용하려고 한다면 Visual Web Developer 2010 Express도 설치합니다.

기본 구성 요소 설치가 끝나면 http://www.codeplex.com/phalanger에서 최신 버전의 Phalanger 설치 프로그램을 다운로드하여 설치를 시작합니다. Phalanger 설치 프로그램 안에는 런타임과 Visual Studio 도구가 모두 들어있습니다. 웹 개발에는 Visual Studio 도구가 따로 필요하지 않으며, Phalanger를 이용해서 PHP/PEAR와 같은 응용프로그램 개발을 하기 원한다면 Visual Studio 도구를 사용하는 것이 편합니다.

WebMatrix에서 Phalanger 사용하기

기본적으로 WebMatrix는 PHP4와 PHP5를 지원합니다. 그러나 WebMatrix가 기본으로 제공하는 PHP 런타임은 사용하지 않고 앞 단계에서 설치한 Phalanger 런타임을 대신 불러오도록 설정을 업데이트할 것입니다. 그러면서도, 기존의 PHP 개발 템플릿을 그대로 이용할 수 있습니다.

WebMatrix에서 Phalanger를 사용하는 방법은 간단합니다. 여러분이 원하는대로 사이트를 하나 새로 만들고, 사이트 탭을 클릭하고 설정 메뉴를 클릭하면 아래와 같이 화면이 나타납니다. 그림에 적은 설명대로, .NET Framework는 버전 4.0을 사용해야 하며, PHP 설정은 사용하지 않고, 필요하다면 index.php가 기본 페이지로 지정되도록 합니다.

이제 파일 탭을 클릭하고 F5키를 눌러 web.config 파일이 있는지 확인합니다. 만약 없다면 web.config 파일을 새 파일로 하나 추가합니다. web.config 템플릿이 WebMatrix에 기본으로 제공되므로 쉽게 추가할 수 있을 것입니다.

참고로 web.config은 기존의 ASP.NET 환경에서도 쓰이지만 WebMatrix가 내부적으로 서버로 사용하는 IIS 7 Express 및 IIS 7의 설정 파일로도 사용되며, IIS 6 이하에서 사용하던 메타베이스 기반 설정과는 달리 Apache HTTP Server의 httpd.conf와 같은 맥락의 디렉터리 단위 설정 파일이라고 보면 되겠습니다.

web.config 파일을 열어서 <system.webServer> XML 요소 아래의 내용을 수정해야 합니다. (다른 부분이 있더라도 여기서는 필요하지 않습니다.) 아래의 내용을 추가하여 PHP 확장자에 대한 지원을 추가하도록 합니다.

<handlers>
  <add name="PhalangerHandler" path="*.php" verb="*" type="PHP.Core.RequestHandler, PhpNetCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=0a8e8c4c76728c71" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>

파일을 저장하고, 잘 작동하는지 테스트하기 위하여 index.php 파일을 만들고 아래와 같이 코드를 작성합니다. 그리고 상단의 실행 버튼을 눌러 잘 나타나는지 확인합니다.

<?php

class myClass {
    var $x;
}

$test = new myClass();
$test->x = "Hello, World! in ";
print $test->x.'<br />';
print get_class($test);

phpinfo();

?>

그러면 아래와 같이 화면이 나타날 것입니다. 클래스를 선언하고, 변수 필드를 선언하고, 여기에 값을 대입하거나 print 문을 사용하여 문자열을 출력하고, get_class 같은 간단한 형식 조회 함수도 씁니다. 아, 그리고 phpinfo 함수는 PHP 세계에서는 매우 기초적이고도 기본적인 함수였죠. :-)

그리고 흔히 사용하는 include_once 같은 API도 잘 작동합니다. 같은 디렉터리 상에 test.php를 만들고 class 선언만 따로 떼어 저장한 다음 include_once 함수를 호출해보기 바랍니다.

test.php

<?php
class myClass {
    var $x;
}

?>

index.php

<?php

include_once('test.php');

$test = new myClass();
$test->x = "Hello, World! in ";
print $test->x.'<br />';
print get_class($test);

phpinfo();

?>

Phalanger에서 한글을 사용하려면

PHP4나 PHP5와 다를바 없는 실행 모습입니다. 그런데 한 가지 점검해봐야 할 것이 있습니다. Phalanger에서 한국어나 일본어같은 2바이트 문자를 정상적으로 취급할 수 있을까요? 기본 설정으로는 그렇지 않을 가능성이 있습니다. 그리고 웹 매트릭스는 모든 파일을 UTF-8로 저장하기 때문에 문제가 됩니다. 이러한 문제를 예방하기 위해서는 반드시 web.config 설정을 변경해야 합니다.

<system.web> 요소 아래에 다음의 코드를 추가하도록 합니다.

<globalization requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="utf-8" />

그리고 앞의 코드에서 한국어 문자열을 포함하는 print 명령문을 한 번 더 추가하여 한글이 잘 나오는지 확인합니다.

이제 Phalanger를 WebMatrix에서 개발할 준비는 다 끝났습니다. 다음 아티클에서는 Phalanger만의 고유한 기술적 특징을 살펴보면서, Phalanger를 C#과 VB.NET과 함께 사용하는 방법을 살펴보도록 하겠습니다. :-)

저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License

'Web Development > Phalanger' 카테고리의 다른 글

Phalanger와 PHP의 차이점들  (0) 2012/02/10
PHP x C# x VB.NET = ASP.NET  (0) 2012/02/08
Phalanger와 WebMatrix의 완벽한 만남  (1) 2012/02/06
PHP와 .NET의 완벽한 만남 - Phalanger  (0) 2012/02/04
Posted by Windows Azure MVP 남정현 (rkttu.com)

오늘은 .NET Framework 4 에서 가장 많은 충돌을 야기할 수 있는 변동 사항 중 하나를 오늘 아티클에서 잠시 다루어보기로 하겠습니다. 바로 ISerializable 인터페이스에 관한 것인데요, Serializable Attribute와 NonSerialized Attribute를 이용하여 제어하는 것 만으로는 불충분한 경우 즐겨 사용해오던 인터페이스입니다. 그렇지만 여기에 급격한 변화 (Breaking Changes)가 .NET Framework 4에 더해지게 되었는데, Partial Trust Mode로 실행되는 어셈블리에서 이 인터페이스를 구현하는 로직을 호출하게 되는 경우, ISerializable 인터페이스의 GetObjectData에 추가된 SecurityCritical Attribute에 의해 호출이 거부됩니다.

저 개인적으로는 XML-RPC의 .NET Framework 버전의 Implementation 라이브러리 (http://www.xml-rpc.net/)를 .NET Framework 4로 업그레이드하여 Windows Azure에 Deploy하면서 이러한 현상을 겪었는데, 이 라이브러리에서 제공하는 Custom Exception 클래스 상의 GetObjectData 메서드가 문제의 원인이 되었습니다. .NET Framework 4 환경에서 사용하도록 별도의 프로젝트 파일을 만들어서 Predefine Condition을 부여하여 ISerializable 인터페이스를 이용하지 않도록 코드를 수정한 이후에는 문제가 잘 해결되었습니다.

만약 ISerializable 인터페이스의 기능을 그대로 가져갈 필요가 있다면, http://msdn.microsoft.com/en-us/library/system.runtime.serialization.isafeserializationdata.aspx 의 내용을 참고하시어 ISafeSerializationData 인터페이스를 구현하는 별도의 코드를 작성해야 합니다. 아래는 MSDN Library에서 발췌한 샘플 코드입니다.


using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
using System.Security;

// [assembly: SecurityCritical(SecurityCriticalScope.Everything)]
// Using the SecurityCriticalAttribute prohibits usage of the
// ISafeSerializationData interface.
[assembly: AllowPartiallyTrustedCallers]
namespace ISafeSerializationDataExample
{
    class Test
    {
        public static void Main()
        {
            try
            {
                // This code forces a division by 0 and catches the
                // resulting exception.
                try
                {
                    int zero = 0;
                    int ecks = 1 / zero;
                }
                catch (Exception ex)
                {
                    // Create a new exception to throw.
                    NewException newExcept = new NewException("Divided by", 0);

                    // This FileStream is used for the serialization.
                    FileStream fs =
                        new FileStream("NewException.dat",
                            FileMode.Create);

                    try
                    {
                        // Serialize the exception.
                        BinaryFormatter formatter = new BinaryFormatter();
                        formatter.Serialize(fs, newExcept);

                        // Rewind the stream and deserialize the exception.
                        fs.Position = 0;
                        NewException deserExcept =
                            (NewException)formatter.Deserialize(fs);
                        Console.WriteLine(
                        "Forced a division by 0, caught the resulting exception, \n" +
                        "and created a derived exception with custom data. \n" +
                        "Serialized the exception and deserialized it:\n");
                        Console.WriteLine("StringData: {0}", deserExcept.StringData);
                        Console.WriteLine("intData:   {0}", deserExcept.IntData);
                    }
                    catch (SerializationException se)
                    {
                        Console.WriteLine("Failed to serialize: {0}",
                            se.ToString());
                    }
                    finally
                    {
                        fs.Close();
                        Console.ReadLine();
                    }
                }
            }
            catch (NewException ex)
            {
                Console.WriteLine("StringData: {0}", ex.StringData);
                Console.WriteLine("IntData:   {0}", ex.IntData);
            }
        }
    }

    [Serializable]
    public class NewException : Exception
    {
        // Because we don't want the exception state to be serialized normally,
        // we take care of that in the constructor.
        [NonSerialized]
        private NewExceptionState m_state = new NewExceptionState();

        public NewException(string stringData, int intData)
        {
            // Instance data is stored directly in the exception state object.
            m_state.StringData = stringData;
            m_state.IntData = intData;

            // In response to SerializeObjectState, we need to provide
            // any state to serialize with the exception.  In this
            // case, since our state is already stored in an
            // ISafeSerializationData implementation, we can
            // just provide that.

            SerializeObjectState += delegate(object exception,
                SafeSerializationEventArgs eventArgs)
            {
                eventArgs.AddSerializedState(m_state);
            };
            // An alternate implementation would be to store the state
            // as local member variables, and in response to this
            // method create a new instance of an ISafeSerializationData
            // object and populate it with the local state here before
            // passing it through to AddSerializedState.       

        }
        // There is no need to supply a deserialization constructor
        // (with SerializationInfo and StreamingContext parameters),
        // and no need to supply a GetObjectData implementation.


        // Data access is through the state object (m_State).
        public string StringData
        {
            get { return m_state.StringData; }
        }

        public int IntData
        {
            get { return m_state.IntData; }
        }

        // Implement the ISafeSerializationData interface
        // to contain custom  exception data in a partially trusted
       // assembly. Use this interface to replace the
       // Exception.GetObjectData method,
        // which is now marked with the SecurityCriticalAttribute.
        [Serializable]
        private struct NewExceptionState : ISafeSerializationData
        {
            private string m_stringData;
            private int m_intData;

            public string StringData
            {
                get { return m_stringData; }
                set { m_stringData = value; }
            }

            public int IntData
            {
                get { return m_intData; }
                set { m_intData = value; }
            }

            // This method is called when deserialization of the
            // exception is complete.
            void ISafeSerializationData.CompleteDeserialization
                (object obj)
            {
                // Since the exception simply contains an instance of
                // the exception state object, we can repopulate it
                // here by just setting its instance field to be equal
                // to this deserialized state instance.
                NewException exception = obj as NewException;
                exception.m_state = this;
            }
        }
    }
}

또는, 코드의 수정을 최소화하기 위하여 설정 파일 (app.config이나 web.config)에 LegacyCASMode Property를 사용하도록 설정을 구성할 수 있습니다. 이에 대한 내용은 http://msdn.microsoft.com/ko-kr/library/tkscy493.aspx 의 내용을 참고하시면 됩니다. 아래는 MSDN Library에서 발췌한 사용 예시입니다.

<location allowOverride="false">
  <system.web>
    <securityPolicy>
      <trustLevel name="Full" policyFile="internal" />
      <trustLevel name="High" policyFile="web_hightrust.config" />
      <trustLevel name="Medium" policyFile="web_mediumtrust.config" />
      <trustLevel name="Low"  policyFile="web_lowtrust.config" />
      <trustLevel name="Minimal" policyFile="web_minimaltrust.config"/>
    </securityPolicy>
  </system.web>
</location>

<location allowOverride="false">
  <system.web>
    <trust level="Medium" originUrl="" />
  </system.web>
</location>

<location allowOverride="true" path="Default Web Site/Temp">
  <system.web>
    <trust level="Medium" originUrl="" />
  </system.web>
</location>

 

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

Microsoft .NET이 처음 소개되어 전세계적으로 널리 사용되어지기 시작한지 어느덧 10년에 가까워져 가고 있습니다. 차세대 .NET 기술이 일정한 주기마다 한번씩 새롭게 리뉴얼이 되고 발표되고 있습니다만 이번에는 다른 때보다 더욱 특별한 의미를 가지게 되는 것 같습니다.

 

금번 국내에서 열리는 Microsoft Techday 행사는 Windows 7, Windows Server 2008 R2를 중심으로, 조만간 발표될 .NET Framework 4.0, Visual Studio 2010, Exchange Server 2010, Expression Series 3와 같은 새로운 제품과 기술들을 살펴볼 수 있음은 물론, Microsoft가 생각하는, .NET 기술을 통한 차세대 컴퓨팅 기술의 전망이 무엇인지를 잘 보여주는 그런 행사가 될 것입니다.

 

Techday 행사는 크게 두 트랙으로 구분되며, 개발자들을 위한 트랙과 IT 전문가들을 위한 트랙으로 구성되어있습니다. 전체 행사는 온라인 세미나의 형태로 진행이 되며, 국내에서 활동하시는 MVP 분들과 에반젤리스트 분들의 세션을 들으실 수 있습니다. 그리고 개인적으로는 키노트의 내용이 상당히 흥미로운 점이 많은것 같습니다. :-)

 

다음의 URL을 통하여 Agenda를 살펴보고 여러분께서 원하시는 세션을 선택하시면 됩니다.

 

http://techdays.co.kr/Sessions/

 

최신 트렌드나 기술에 대해서 정보를 빠르고 정확하게 구할 수 있는 자리는 그렇게 흔하지 않을 것입니다. 이번 Techday 행사를 통하여 Microsoft의 기술 비전을 공유하고, 체험할 수 있는 기회를 꼭 마련하시기 바랍니다.


 

컴퓨팅 플랫폼의 획기적인 변화는 기업의 데이터 센터에서 우리 가정의 PC와 웹 브라우저,
그리고 내 손 안의 디바이스 단말까지 모든 일상을 바꾸고 있습니다. 또한 불확실한 미래와 비용 절감의 압박은
비즈니스에서 IT의 역할을 더욱 강화시키고 있습니다.

마이크로소프트는 10월 말 출시 예정인 새로운 운영 체제 Windows 7을 비롯하여
Visual Studio 2010, Expression 3, Windows Server 2008 R2, Exchange 2010을 비롯한 다양하고 우수한 기술로
개발자와 IT 전문가들의 새로운 시대를 열어드리고자 합니다.

클라이언트부터 웹, 모바일, 서버 그리고 클라우드까지 최신 플랫폼과 기술 트렌드를 한 자리에서 만나볼 수 있는
국내 최대 온라인 컨퍼런스 TechDays 2009에서 주요 기술 흐름을 점검하시기 바랍니다.

감사합니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)