localdisk

PHP とか Java とか Web とか好きなことを書きます。

PHPでjQueryっぽく書けるPHPQueryってやつを作った

         ,. -‐'''''""¨¨¨ヽ
         (.___,,,... -ァァフ|          あ…ありのまま 今 起こった事を話すぜ!
          |i i|    }! }} //|
         |l、{   j} /,,ィ//|       『PHPテンプレートエンジンを自作していたら
        i|:!ヾ、_ノ/ u {:}//ヘ        いつの間にかjQueryもどきをPHPで実装してた』
        |リ u' }  ,ノ _,!V,ハ |
       /´fト、_{ル{,ィ'eラ , タ人        な… 何を言ってるのか わからねーと思うが
     /'   ヾ|宀| {´,)⌒`/ |<ヽトiゝ        おれも何をされたのかわからなかった
    ,゙  / )ヽ iLレ  u' | | ヾlトハ〉
     |/_/  ハ !ニ⊇ '/:}  V:::::ヽ        頭がどうにかなりそうだった…
    // 二二二7'T'' /u' __ /:::::::/`ヽ
   /'´r -―一ァ‐゙T´ '"´ /::::/-‐  \    超スピードだとか催眠術だとか
   / //   广¨´  /'   /:::::/´ ̄`ヽ ⌒ヽ    そんなチャチなもんじゃあ 断じてねえ
  ノ ' /  ノ:::::`ー-、___/::::://       ヽ  }
_/`丶 /:::::::::::::::::::::::::: ̄`ー-{:::...       イ  もっと恐ろしいものの片鱗を味わったぜ… 

というわけで

自作のテンプレートエンジンの副産物であるPHPQueryを公開しておきます。こんな感じで使えます。

<?php
    require_once 'PHPQuery.php';
    $p = new PHPQuery('test.html');
    echo $p->id('hoge')->attr(array('title'=>'foo'))->addClass('bar')->text('てきすと')->write();

Domdocumentをベースにしてます。動かしてて中々楽しいです。

ソース

<?php
class PHPQuery {
    /**
     * Element
     *
     * @var DOMElement
     */
    private $_elem;
    /**
     *  Document
     * 
     * @var DOMDocument
     */
    private $_dom;
    /**
     * Constructor
     */
    public function __construct($html) {
        $this->_dom = new DOMDocument();
        $this->_dom->formatOutput = true;
        $this->load($html);
    }
    /**
     * get id
     * 
     * @param  string $id
     * @return PHPQuery
     */
    public function id($id) {
        $this->_elem = $this->_dom->getElementById($id);
        return $this;
    }
    /**
     * load html
     * 
     * @param  string $html
     * @return PHPQuery
     */
    public function load($html) {
        if (is_file($html)) {
            $this->_dom->loadHTMLFile($html);
        } else {
            $this->_dom->loadHTML($html);
        }
        return $this;
    }
    /**
     * set and get Attribute
     *
     * @param  string|array $key
     * @param  string $value
     * @return string|PHPQuery
     */
    public function attr($key = null, $value = null) {
        if ($value === null) {
            if (is_string($key)) {
                return $this->_elem->getAttribute($key);
            } elseif (is_array($key)) {
                foreach ($key as $k => $v) {
                    $this->_elem->setAttribute((string)$k, (string)$v);
                }
                return $this;
            }
        } else {
            $this->_elem->setAttribute((string)$key, (string)$value);
            return $this;
        }
    }
    /**
     * removeAttribute
     *
     * @param  string $name
     * @return PHPQuery
     */
    public function removeAttr($name = null) {
        if ($name === null) throw new Exception('$name is null');
        $this->_elem->removeAttribute($name);
        return $this;
    }
    /**
     * add class
     *
     * @param  string $class
     * @return PHPQuery
     */
    public function addClass($class = null) {
        if ($class === null) throw new Exception('$class is null');
        $clazz = $this->attr('class');
        $clazz .= ' ' . $class;
        $this->attr('class', $clazz);
        return $this;
    }
    /**
     * remove class
     *
     * @param  string $class
     * @return PHPQuery
     */
    public function removeClass($class = null) {
        if ($class === null) throw new Exception('$class is null');
        $clazz = explode(' ', $this->attr('class'));
        $a = array();
        foreach ($clazz as $c) {
            if (empty($c) || strcmp($class, $c) === 0) {
                continue;
            }
            $a[] = $c;
        }
        $this->attr('class', implode(' ', $a));
        return $this;
    }
    /**
     * add or remove class
     *
     * @param  string $class
     * @return PHPQuery
     */
    public function toggleClass($class = null) {
        if ($class === null) throw new Exception('$class is null');
        $clazz = explode(' ', $this->attr('class'));
        foreach ($clazz as $c) {
            if (strcmp($c, $class) === 0) {
                return $this->removeClass($class);
            }
        }
        return $this->addClass($class);
    }
    /**
     * set or get html
     *
     * @param  string $val
     * @return string|PHPQuery
     */
    public function html($val = null) {
        if ($val === null) {
            $nodes = $this->_elem->childNodes;
            $txt = '';
            foreach ($nodes as $node) {
                $name = $node->nodeName;
                $value = $node->nodeValue;
                if ($name !== '#text') {
                    $txt .= '<' . $name;
                    if ($node->attributes !== null) {
                        foreach ($node->attributes as $k) {
                            $txt .= ' ' . $k->name . '="' . $k->value . '"';
                        }
                    }
                    $txt .= '>';
                    $txt .= $value;
                    $txt .= '</' . $name . '>';
                } else {
                    $txt .= $value;
                }
            }
            return $txt;
        } else {
            $this->clean()->append($val);
        }
        return $this;
    }
    /**
     * set or get value
     *
     * @param  string $val
     * @return string|PHPQuery
     */
    public function val($val = null) {
        if ($val === null) {
            return $this->_elem->getAttribute('value');
        } else {
            $this->_elem->setAttribute('value', (string)$val);
        }
        return $this;
    }
    /**
     * get or set text
     * 
     * @param  string $val
     * @return string|PHPQuery
     */
    public function text($val = null) {
        if ($val === null) {
            return $this->_elem->textContent;
        } else {
            $this->clean()->appendText($val);
            return $this;
        }
    }
    /**
     * clean child element
     * 
     * @return PHPQuery
     */
    public function clean() {
        while($this->_elem->hasChildNodes()) {
            $nodes = $this->_elem->childNodes;
            foreach($nodes as $node) {
                $this->_elem->removeChild($node);
            }
        }
        return $this;
    }
    /**
     * append string
     *
     * @param  string $str
     * @return PHPQuery
     */
    public function append($str) {
        $newdoc = new DOMDocument();
        $newdoc->loadHTML($str);
        $body = $newdoc->getElementsByTagName('body')->item(0);
        $nodes = $body->childNodes;
        foreach ($nodes as $node) {
            $e = $this->_dom->importNode($node, true);
            $this->_elem->appendChild($e);
        }
        return $this;
    }
    /**
     * append text
     *
     * @param  string $str
     * @return PHPQuery
     */
    public function appendText($str) {
        $doc = $this->_dom;
        $e = $doc->createTextNode($str);
        $this->_elem->appendChild($e);
        return $this;
    }
    /**
     * write html
     * 
     * @return string
     */
    public function write() {
        return $this->_dom->saveHTML();
    }
    /**
     * write html file
     * 
     * @param string $fileName
     */
    public function writeFile($fileName = null) {
        if ($fileName === null) throw new Exception('$fileName is null');
        $this->_dom->saveHTMLFile($fileName);
    }
}
         ,. -‐'''''""¨¨¨ヽ
         (.___,,,... -ァァフ|          あ…ありのまま 今 起こった事を話すぜ!
          |i i|    }! }} //|
         |l、{   j} /,,ィ//|       『せっかく作ったのでブログに書く前に、何の気なしにぐぐったら
        i|:!ヾ、_ノ/ u {:}//ヘ        俺のものより数段高機能なphpqueryってものが存在してた』
        |リ u' }  ,ノ _,!V,ハ |       http://code.google.com/p/phpquery/
       /´fト、_{ル{,ィ'eラ , タ人        な… 何を言ってるのか わからねーと思うが
     /'   ヾ|宀| {´,)⌒`/ |<ヽトiゝ        おれも何をされたのかわからなかった
    ,゙  / )ヽ iLレ  u' | | ヾlトハ〉
     |/_/  ハ !ニ⊇ '/:}  V:::::ヽ        頭がどうにかなりそうだった…
    // 二二二7'T'' /u' __ /:::::::/`ヽ
   /'´r -―一ァ‐゙T´ '"´ /::::/-‐  \    車輪の再発明だとか
   / //   广¨´  /'   /:::::/´ ̄`ヽ ⌒ヽ    そんなチャチなもんじゃあ 断じてねえ
  ノ ' /  ノ:::::`ー-、___/::::://       ヽ  }
_/`丶 /:::::::::::::::::::::::::: ̄`ー-{:::...       イ  もっと恐ろしいものの片鱗を味わったぜ…