PHP로 Excel 데이터 읽고 쓰기
XML 지원 사용하기 요약: Microsoft® Excel® 2003에서 내보낸 XML에서 데이터를 읽기 위해 PHP에서 XML 지원을 사용하는 방법에 대해 알아봅니다. 또한 Excel XML로 PHP 애플리케이션에서부터 데이터를 내보내는 것을 배워서 사용자가 실제 스프레드시트에서 데이터를 확인할 수 있습니다.
XML 파일 형식이 그렇게 중요한 이유는 무엇인가? 수 년 동안 Excel 또는 Word의 실제 성능은 정교한 변환기가 액세스해야 하는 2진 파일 형식에 묻혀 있었다. 이제는 PHP 프로그래밍 언어에 내장된 Extensible Stylesheet Language Transformation(XSLT)이나 XML Document Object Model(DOM) 함수와 같이 XML 도구를 사용하여 Excel 또는 Word 파일을 읽거나 쓸 수 있다.
이 기사에서는 이러한 형식을 사용하여 Excel 스프레드시트에서부터 데이터를 데이터베이스로 읽고 데이터베이스 테이블의 내용을 Excel 스프레드시트로 내보내도록 PHP 웹 애플리케이션을 빌드하는 방법을 알려준다.
데이터베이스 작성
이 기사에서 필자가 간단한 웹 애플리케이션을 사용하여 Excel XML 메커니즘을 명확히 확인할 수 있다. 이 애플리케이션은 이름과 이메일 주소의 테이블이다.
MySQL 구문에서 스키마는 목록 1에서 코드의 모양과 같다.
목록 1. 데이터베이스용 SQL
DROP TABLE IF EXISTS names; CREATE TABLE names ( id INT NOT NULL AUTO_INCREMENT, first TEXT, middle TEXT, last TEXT, email TEXT, PRIMARY KEY( id ) ); |
이 파일은 싱글 테이블 데이터베이스이며, 테이블 -- names -- 에는 자동 증분하는 ID 필드에 이어서 이름, 중간 이름 및 성 필드와 이메일 필드 등 5개의 필드가 있다.
데이터베이스를 설정하려면 Mysqladmin 명령행 도구인
mysqladmin --user=root create names
를 사용하는 데이터베이스를 작성한다. 그 다음에 스키마 파일인 mysql --user=root names < schema.sql
에서부터 데이터베이스를 로드한다. 사용하는 사용자 및 비밀번호 인증은 설치에 따라 다르지만, 그 개념은 동일하다. 먼저 데이터베이스를 작성한다. 그 다음에 SQL 파일을 사용하여 필수 필드로 테이블을 작성한다.가져오기 데이터 작성
다음 단계는 가져오기를 위한 일부 데이터를 작성하는 것이다. 새 Excel 파일을 작성한다. 첫 번째 워크북에서 First, Middle, Last 및 Email 열의 첫 번째 행을 호출한다. 그 다음에 데이터의 몇 개의 행을 목록에 추가한다(그림 1 참조).
그림 1. 가져오기용 데이터
필드를 원하거나 변경하는 대로 목록을 만들 수 있지만 맞는 것을 확인한다. 이 기사에서 PHP 가져오기 스크립트는 데이터의 첫 행이 헤더 행이라고 가정하기 때문에 이를 무조건 무시한다. 프로덕션 애플리케이션에서는 어느 필드가 어느 열인지 결정하고 가져오기 논리에 맞도록 적절하게 변경하기 위한 헤더 행을 읽고 구문 분석하려 할 것이다.
마지막 단계는 File > Save As를 클릭한 다음에 Save As 창에서 Save as type 드롭다운 목록에서부터 XML Spreadsheet를 선택하여 파일을 XML로 저장하는 것이다(그림 2 참조).
그림 2. 파일을 XML 스프레드시트로 저장
XML 파일을 가지고 이를 통해 PHP 애플리케이션 개발을 시작할 수 있다.
데이터 가져오기
가져오기 시스템은 입력 Excel XML 파일을 지정하는 페이지를 사용하여 간편하게 시작할 수 있다(그림 3 참조).
그림 3. 입력 Excel XML 파일 지정
페이지 논리는 목록 2에 보여주는 대로 간단하다.
목록 2. 업로드 페이지 코드
<html> <body> <form enctype="multipart/form-data" action="import.php" method="post"> <input type="hidden" name="MAX_FILE_SIZE" value="2000000" /> <table width="600"> <tr> <td>Names file:</td> <td><input type="file" name="file" /></td> <td><input type="submit" value="Upload" /></td> </tr> </table> </form> </body> </html> |
파일을 .php 확장자로 이름을 지정했지만 실제로는 PHP가 아니다. 이는 사용자가 파일을 지정할 수 있고 이 파일을 실제로 중요한 일이 발생하는 import.php 페이지로 제출하는 HTML 파일에 불과하다.
Excel XML 데이터 읽기
필자는 더 쉽게 따라하기 위해 두 단계에서 import.php 페이지를 썼다. 첫 번째 단계에서 필자는 간단하게 XML 데이터를 구문분석하고 이를 테이블로 출력한다. 두 번째 단계에서는 레코드를 데이터베이스로 삽입하는 논리를 추가한다.
목록 3에는 예제 Excel 2003 XML 파일을 보여준다.
목록 3. 샘플 Excel XML 파일
<?xml version="1.0"?> <?mso-application progid="Excel.Sheet"?> <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40"> <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"> <Author>Jack Herrington</Author> <LastAuthor>Jack Herrington</LastAuthor> <Created>2005-08-02T04:06:26Z</Created> <LastSaved>2005-08-02T04:30:11Z</LastSaved> <Company>My Software Company, Inc.</Company> <Version>11.6360</Version> </DocumentProperties> <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"> <WindowHeight>8535</WindowHeight> <WindowWidth>12345</WindowWidth> <WindowTopX>480</WindowTopX> <WindowTopY>90</WindowTopY> <ProtectStructure>False</ProtectStructure> <ProtectWindows>False</ProtectWindows> </ExcelWorkbook> <Styles> <Style ss:ID="Default" ss:Name="Normal"> <Alignment ss:Vertical="Bottom"/> <Borders/> <Font/> <Interior/> <NumberFormat/> <Protection/> </Style> <Style ss:ID="s21" ss:Name="Hyperlink"> <Font ss:Color="#0000FF" ss:Underline="Single"/> </Style> <Style ss:ID="s23"> <Font x:Family="Swiss" ss:Bold="1"/> </Style> </Styles> <Worksheet ss:Name="Sheet1"> <Table ss:ExpandedColumnCount="4" ss:ExpandedRowCount="5" x:FullColumns="1" x:FullRows="1"> <Column ss:Index="4" ss:AutoFitWidth="0" ss:Width="154.5"/> <Row ss:StyleID="s23"> <Cell><Data ss:Type="String">First</Data></Cell> <Cell><Data ss:Type="String">Middle</Data></Cell> <Cell><Data ss:Type="String">Last</Data></Cell> <Cell><Data ss:Type="String">Email</Data></Cell> </Row> <Row> <Cell><Data ss:Type="String">Molly</Data></Cell> <Cell ss:Index="3"><Data ss:Type="String">Katzen</Data></Cell> <Cell ss:StyleID="s21" ss:HRef="mailto:molly@katzen.com"> <Data ss:Type="String">molly@katzen.com</Data></Cell> </Row> ... </Table> <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"> <Print> <ValidPrinterInfo/> <HorizontalResolution>300</HorizontalResolution> <VerticalResolution>300</VerticalResolution> </Print> <Selected/> <Panes> <Pane> <Number>3</Number> <ActiveRow>5</ActiveRow> </Pane> </Panes> <ProtectObjects>False</ProtectObjects> <ProtectScenarios>False</ProtectScenarios> </WorksheetOptions> </Worksheet> <Worksheet ss:Name="Sheet2"> <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"> <ProtectObjects>False</ProtectObjects> <ProtectScenarios>False</ProtectScenarios> </WorksheetOptions> </Worksheet> <Worksheet ss:Name="Sheet3"> <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"> <ProtectObjects>False</ProtectObjects> <ProtectScenarios>False</ProtectScenarios> </WorksheetOptions> </Worksheet> </Workbook> |
필자는 중간에 몇 개의 행을 잘라냈지만, 그렇지 않으면 파일은 Excel에서 나온 그대로이다. 이는 상대적으로 정리된 XML이다. 초반부의 문서 헤더 부분에 문서와 그 저자를 설명하고 일부 시각적 정보를 늘어놓고 스타일을 나열하는 것을 유의하자. 그 다음에 데이터가 기본
Workbook
오브젝트에서 워크시트의 세트로 제공된다.첫 번째
Worksheet
오브젝트에는 실제 데이터가 들어있다. 이 오브젝트에서 데이터는 Table
태그에서 Row
와 Cell
태그의 세트로 남아있다. 각 Cell
태그에는 셀에 대한 데이터를 보유하는 이와 연관된 Data
태그가 있다. 이 경우에 데이터는 언제나 String 유형으로 형식화된다.기본값으로 새 문서를 작성할 때에 Excel은 Sheet1, Sheet2 및 Sheet3이라는 세 개의 워크시트를 작성한다. 필자는 두 번째와 세 번째 워크시트를 삭제하지 않았기 때문에 문서의 끝부분에 이러한 빈 워크북이 보인다.
목록 4에는 import.php 스크립트의 첫 번째 버전을 보여준다.
목록 4. 가져오기 스크립트의 첫 번째 버전
<?php $data = array(); function add_person( $first, $middle, $last, $email ) { global $data; $data []= array( 'first' => $first, 'middle' => $middle, 'last' => $last, 'email' => $email ); } if ( $_FILES['file']['tmp_name'] ) { $dom = DOMDocument::load( $_FILES['file']['tmp_name'] ); $rows = $dom->getElementsByTagName( 'Row' ); $first_row = true; foreach ($rows as $row) { if ( !$first_row ) { $first = ""; $middle = ""; $last = ""; $email = ""; $index = 1; $cells = $row->getElementsByTagName( 'Cell' ); foreach( $cells as $cell ) { $ind = $cell->getAttribute( 'Index' ); if ( $ind != null ) $index = $ind; if ( $index == 1 ) $first = $cell->nodeValue; if ( $index == 2 ) $middle = $cell->nodeValue; if ( $index == 3 ) $last = $cell->nodeValue; if ( $index == 4 ) $email = $cell->nodeValue; $index += 1; } add_person( $first, $middle, $last, $email ); } $first_row = false; } } ?> <html> <body> <table> <tr> <th>First</th> <th>Middle</th> <th>Last</th> <th>Email</th> </tr> <?php foreach( $data as $row ) { ?> <tr> <td><?php echo( $row['first'] ); ?></td> <td><?php echo( $row['middle'] ); ?></td> <td><?php echo( $row['last'] ); ?></td> <td><?php echo( $row['email'] ); ?></td> </tr> <?php } ?> </table> </body> </html> |
스크립트는 업로드된 임시 파일에서
DOMDocument
오브젝트로 읽으면서 시작된다. 그 다음에 스크립트가 각 Row
태그를 찾는다. 첫 번째 행은 $first_row
변수와 연관된 논리를 사용하여 무시된다. 첫 번째 행 이후에 내부 루프는 행에서 각 Cell
태그를 구문 분석한다.그 다음에 까다로운 것은 어느 열에 있는지를 파악하는 것이다. XML에서 확인 가능한 대로
Cell
태그는 열이나 행 수를 지정하지 않는다. 스크립트는 이를 그 자체로 추적해야 한다. 실제로는 이보다 훨씬 더 복잡하다. 사실 Cell
태그는 이 행에 빈 열이 있는 경우 셀이 어느 열에 있는지 알려주는 ss:Index
속성이 있다. 이는 getAttribute('index')
코드가 찾고 있는 것이다.색인을 결정한 후에 코드는 간단하다. 셀 값을 해당 필드와 연관된 로컬 값에 놓는다. 그 다음에 행의 끝에서
add_person
함수를 호출하여 그 사람을 데이터 세트에 추가한다.PHP는 페이지의 끝에서 익숙한 PHP 메커니즘을 사용하여 HTML 테이블로 찾은 데이터를 출력한다(그림 4 참조).
그림 4. HTML 테이블로 데이터 출력
다음 단계는 이 데이터를 데이터베이스로 로드하는 것이다.
데이터를 데이터베이스에 추가
스크립트는 PHP 데이터 구조에서 행 데이터를 가진 후에 해당 데이터를 데이터베이스로 추가해야 한다. 이를 수행하기 위해서 Pear DB 모듈을 사용하는 일부 코드를 추가했다(목록 5 참조).
목록 5. 가져오기 스크립트의 두 번째 버전
<?php require_once( "db.php" ); $data = array(); $db =& DB::connect("mysql://root@localhost/names", array()); if (PEAR::isError($db)) { die($db->getMessage()); } function add_person( $first, $middle, $last, $email ) { global $data, $db; $sth = $db->prepare( "INSERT INTO names VALUES( 0, ?, ?, ?, ? )" ); $db->execute( $sth, array( $first, $middle, $last, $email ) ); $data []= array( 'first' => $first, 'middle' => $middle, 'last' => $last, 'email' => $email ); } if ( $_FILES['file']['tmp_name'] ) { $dom = DOMDocument::load( $_FILES['file']['tmp_name'] ); $rows = $dom->getElementsByTagName( 'Row' ); $first_row = true; foreach ($rows as $row) { if ( !$first_row ) { $first = ""; $middle = ""; $last = ""; $email = ""; $index = 1; $cells = $row->getElementsByTagName( 'Cell' ); foreach( $cells as $cell ) { $ind = $cell->getAttribute( 'Index' ); if ( $ind != null ) $index = $ind; if ( $index == 1 ) $first = $cell->nodeValue; if ( $index == 2 ) $middle = $cell->nodeValue; if ( $index == 3 ) $last = $cell->nodeValue; if ( $index == 4 ) $email = $cell->nodeValue; $index += 1; } add_person( $first, $middle, $last, $email ); } $first_row = false; } } ?> <html> <body> These records have been added to the database: <table> <tr> <th>First</th> <th>Middle</th> <th>Last</th> <th>Email</th> </tr> <?php foreach( $data as $row ) { ?> <tr> <td><?php echo( $row['first'] ); ?></td>< <td><?php echo( $row['middle'] ); ?></td>< <td><?php echo( $row['last'] ); ?></td>< <td><?php echo( $row['email'] ); ?></td>< </tr> <?php } ?> </table> Click <a href="list.php">here</a> for the entire table. </body> </html> |
그림 5에는 Firefox에서 결과물을 보여준다.
그림 5. 데이터베이스
특별히 볼 것은 없지만, 그 점은 중요하지 않다. 중요한 점은 데이터베이스 오브젝트의
prepare
및 execute
명령문의 사용을 통해 데이터를 데이터베이스로 추가할 수 있다는 점이다. 이를 증명하기 위해 데이터베이스에서 데이터를 보여주는 list.php라는 또다른 페이지를 작성했다(목록 6 참조).목록 6. List.php
<?php // Install the DB module using 'pear install DB' require_once( "db.php" ); $data = array(); $db =& DB::connect("mysql://root@localhost/names", array()); if (PEAR::isError($db)) { die($db->getMessage()); } $res = $db->query( "SELECT * FROM names ORDER BY last" ); ?> <html> <body> <table> <tr> <th>ID</th> <th>First</th> <th>Middle</th> <th>Last</th> <th>Email</th> </tr> <?php while( $res->fetchInto( $row, DB_FETCHMODE_ASSOC ) ) { ?> <tr> <td><?php echo( $row['id'] ); ?></td> <td><?php echo( $row['first'] ); ?></td> <td><?php echo( $row['middle'] ); ?></td> <td><?php echo( $row['last'] ); ?></td> <td><?php echo( $row['email'] ); ?></td> </tr> <?php } ?> </table> Download as an <a href="listxl.php">Excel spreadsheet</a>. </body> </html> |
이 간단한 페이지는 이름 테이블에 대해 SQL
select
조작을 실행하여 시작된다. 그러면 이는 테이블을 작성하고 fetchInto
메소드를 사용하여 테이블의 모든 행을 추가하여 원시 데이터를 얻는다.그림 6에는 페이지의 결과물을 보여준다.
그림 6. list.php의 결과물
다시 말해 미인 대회의 우승자가 아니라 이 페이지를 이용하여 데이터베이스로 데이터를 얻는 방법의 기본을 설명하였다. 결과적으로 이는 내보내기 위한 Excel XML 파일을 생성할 스크립트의 기초를 제공한다.
내보내기 Excel XML 생성
마지막 단계는 Excel XML을 생성하는 것이다. 필자는 이를 Excel XML을 PHP 스크립트로 복사하여 시작했다(목록 7 참조). 이러한 작업이 게으른 것은 알지만, 정확하게 구문 분석하는 Excel XML 파일을 얻는 가장 간편한 방법이다. (Excel은 XML에 대해 까다롭다.)
목록 7. XML 내보내기 페이지
<?php header( "content-type: text/xml" ); // Install the DB module using 'pear install DB' require_once( "db.php" ); $data = array(); $db =& DB::connect("mysql://root@localhost/names", array()); if (PEAR::isError($db)) { die($db->getMessage()); } $res = $db->query( "SELECT * FROM names ORDER BY last" ); $rows = array(); while( $res->fetchInto( $row, DB_FETCHMODE_ASSOC ) ) { $rows []= $row; } print "<?xml version=\"1.0\"?>\n"; print "<?mso-application progid=\"Excel.Sheet\"?>\n"; ?> <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40"> <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"> <Author>Jack Herrington</Author> <LastAuthor>Jack Herrington</LastAuthor> <Created>2005-08-02T04:06:26Z</Created> <LastSaved>2005-08-02T04:30:11Z</LastSaved> <Company>My Company, Inc.</Company> <Version>11.6360</Version> </DocumentProperties> <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"> <WindowHeight>8535</WindowHeight> <WindowWidth>12345</WindowWidth> <WindowTopX>480</WindowTopX> <WindowTopY>90</WindowTopY> <ProtectStructure>False</ProtectStructure> <ProtectWindows>False</ProtectWindows> </ExcelWorkbook> <Styles> <Style ss:ID="Default" ss:Name="Normal"> <Alignment ss:Vertical="Bottom"/> <Borders/> <Font/> <Interior/> <NumberFormat/> <Protection/> </Style> <Style ss:ID="s21" ss:Name="Hyperlink"> <Font ss:Color="#0000FF" ss:Underline="Single"/> </Style> <Style ss:ID="s23"> <Font x:Family="Swiss" ss:Bold="1"/> </Style> </Styles> <Worksheet ss:Name="Names"> <Table ss:ExpandedColumnCount="4" ss:ExpandedRowCount="<?php echo( count( $rows ) + 1 ); ?>" x:FullColumns="1" x:FullRows="1"> <Column ss:Index="4" ss:AutoFitWidth="0" ss:Width="154.5"/> <Row ss:StyleID="s23"> <Cell><Data ss:Type="String">First</Data></Cell> <Cell><Data ss:Type="String">Middle</Data></Cell> <Cell><Data ss:Type="String">Last</Data></Cell> <Cell><Data ss:Type="String">Email</Data></Cell> </Row> <?php foreach( $rows as $row ) { ?> <Row> <Cell><Data ss:Type="String"><?php echo( $row['first'] ); ?> </Data></Cell> <Cell><Data ss:Type="String"><?php echo( $row['middle'] ); ?> </Data></Cell> <Cell><Data ss:Type="String"><?php echo( $row['last'] ); ?> </Data></Cell> <Cell ss:StyleID="s21"><Data ss:Type="String"> <?php echo( $row['email'] ); ?></Data></Cell> </Row> <?php } ?> </Table> <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"> <Print> <ValidPrinterInfo/> <HorizontalResolution>300</HorizontalResolution> <VerticalResolution>300</VerticalResolution> </Print> <Selected/> <Panes> <Pane> <Number>3</Number> <ActiveRow>1</ActiveRow> </Pane> </Panes> <ProtectObjects>False</ProtectObjects> <ProtectScenarios>False</ProtectScenarios> </WorksheetOptions> </Worksheet> </Workbook> |
스크립트는 XML로 결과물의 내용 유형을 설정하여 시작한다. 이렇게 하지 않으면 브라우저가 이 코드를 단순히 불량 HTML이라고 간주하기 때문에 이 작업이 중요하다.
코드의 SQL 쿼리 부분을 변경하여 쿼리의 결과를 배열로 저장했다. 대개 필자는 이러한 보고 페이지 유형으로 이렇게 작업하지 않지만, 이 경우에 행의 숫자인 1을 추가하여
ss:ExpandedRowCount
속성에 넣어야 한다. 1의 추가(+1)는 헤더 행을 세는 것이다.그림 7에는 링크를 클릭한 결과를 보여준다.
그림 7. Firefox에서 XML 내보내기
엄청나게 대단하지는 않다. 하지만 Internet Explorer에서 동일한 링크를 클릭할 때 나타나는 것을 보자(그림 8 참조).
그림 8. Internet Explorer에서 내보낸 XML
굉장한 차이가 있다. 이는 브라우저 내에서 전체 스프레드시트 -- 형식화 및 기타 등등 -- 이다. (물론 Firefox에서 링크를 마우스 오른쪽 단추로 클릭하고 XML을 파일로 저장하여 이렇게 시작할 수도 있다.)
가능성의 기술
다른 최첨단 기술과 마찬가지로 이 기술에도 약점은 있다. 예를 들어, 최신 Mac용 Office 버전이 XML 파일을 지원하지 않기 때문에 Macintosh에서는 작동하지 않는다.
또다른 문제점은 이러한 파일을 디버깅하면 문제가 될 수 있다는 점이다. XML이 약간만 잘못되어도 내장 Excel 오브젝트는 Excel에서 이는 실행 중이고 시작을 거부한다고 미리 간주하는 불량 상태로 들어가게 된다. 이는 애플리케이션을 다시 시작해야만 수정할 수 있다.
즉, 이 기술은 PHP 프로그래머에게 비할 데 없는 통합 가능성을 제공한다. 데이터의 소스가 Excel이나 Word 등이며 수동으로 웹 애플리케이션으로 마이그레이션 되어야 하는지 -- 셀마다 또는 문단마다 -- 얼마나 자주 알게 되는가? 이와 같은 가져오기 기술을 통해 이 문제가 해결된다. 데이터를 워크시트나 문서에서부터 직접 읽을 수 있다.
이는 내보내기 면에서도 마찬가지이다. HTML은 기사와 글에 대해서는 훌륭하지만, 스프레드시트 정보를 정확하게 렌더링하도록 제작되지는 않았다. 여기에서 보여준 기술을 사용하여 사용자가 보기를 예상하는 방식으로 -- 공식, 형식화 등등 -- 스프레드시트를 생성할 수 있다.
참고자료
교육
- PHP.net는 PHP에 대한 최신 소식을 보고 다운로드를 찾으며 다른 사용자에게서 배울 수 있는 장소이다.
- Microsoft Office Online은 지원을 비롯하여 Office 정보를 얻기 위해 시작하기에 최고의 장소이다.
- XML 표준의 권위 있는 소스는 World Wide Web Consortium(W3C)이다.
- XML in Office 2003: Information Sharing with Desktop XML (Prentice Hall, 2003)은 Charles F. Goldfarb과 Priscilla Walmsley이 지은 완벽한 광범위한 안내서이다.
- 이 2003년 11월의 developerWorks 기사인 "Convert Excel data to XML"은 Excel 파일에서부터 데이터를 잠금 해제하여 XML에서 이를 처리하는 방법을 보여주고 다른 솔루션의 장단점을 조사한다. 이는 Excel 2002 및 Excel XP 클라이언트 소프트웨어에 적합하다.
- developerWorks XML 영역에서 XML 개발자를 위한 더 많은 자원을 찾아보자.
- developerWorks 오픈 소스 영역에서 오픈 소스 기술을 활용하여 개발 작업을 수행하고 이러한 기술을 IBM 제품과 함께 사용하는 데 도움이 되는 사용법 정보, 도구 및 프로젝트 업데이트를 확인할 수 있다.
- DVD로 제공되거나 다운로드할 수 있는 IBM 시험판 소프트웨어를 사용하여 차기 오픈 소스 개발 프로젝트를 구현해 보자.
- developerWorks 블로그를 통해 developerWorks 커뮤니티에 참여하자.
Jack D. Herrington은 20년 경력의 소프트웨어 엔지니어이다. Code Generation in Action, Podcasting Hacks, PHP Hacks(출간 예정)의 저자이기도 하다. 30개 이상의 기술자료도 집필했다. (jack_d_herrington@codegeneration.net)
댓글 없음:
댓글 쓰기