ラベル PHP の投稿を表示しています。 すべての投稿を表示
ラベル PHP の投稿を表示しています。 すべての投稿を表示

2013/02/28

[php] 配列から空要素を取り除く

目からうろこだったのでメモ
$hoge_array = array("", "", "hoge");
$fuga_array = array_diff( $hoge_array, array( "" ) );
print_r($fuga_array );
参考)
phpで、array(配列)の空要素を取り除く - カサヒラボ http://d.hatena.ne.jp/kasahi/20070605/1181027762

2013/02/03

[Mac][MBA(Lion)] php.ini設定

MacでPHP動かしたら mktime()でWarningが出て怒られた

「Warning: mktime(): It is not safe to rely on the 〜」とかなんとか

エラーメッセージ見ると なんか timezoneを設定してよとかいってるぽい

php.ini の 「date.timezone =」を設定してやる必要がある

━━━━━━━━━━━━━━━━━

まず、Macに入ってるPHPは 最初から入ってるやつだから
php.iniどこにあるんだか知らない
とりあえず php infoをターミナルで表示してみる
---------------------
$ php -i | grep ini
Configuration File (php.ini) Path => /etc
Loaded Configuration File => /private/etc/php.ini
Scan this dir for additional .ini files => (none)
Additional .ini files parsed => (none)
 :
 :
(略)
---------------------
/etc にあるらしい
Scan this dir for additional .ini files が noneだと????(ま、いいや

/etc 配下を見ると
-r--r--r--  1 root  wheel  69337  7  8  2011 /etc/php.ini.default
こいつを
cpして(/etc 配下は root権限じゃないと何もできないから、以後 sudo必須)

$ sudo cp php.ini.default php.ini

read onlyだから ぱーみっそん変更して編集

$ sudo chmod 664 php.ini
$ sudo vi php.ini
---------------------
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = 'Asia/Tokyo' ←こんなかんじで。
---------------------

再度、php実行してみて Warningでなかった OK(・ω・)b



2012/07/02

[PHP] Memcache 簡易スクリプト

◎簡単な 確認やら、セットやらできるやつ

→ コマンドラインから、php -f chk_memcached.php get_list みたいに実行

・get_list 表示例

# php -f chk_memcached.php get_list
==============================
command:get_list
==============================
* = old cache
---------------
expire = 0  | size =       10 | cache_key = foo
expire = 0  | size =       20 | cache_key = hoge
---------------
key count:2
     total cache size:        30byte
*old total cache size:         0byte


#define('MEM_HOST', 'localhost');
define('MEM_HOST', '127.0.0.1');
define('MEM_PORT', 11211);

if ($argc < 2) {
  showUsage();
  exit;
}

$output = array();
$keys   = array();
$value  = '';

//Memcache
$memcache_obj = new Memcache;
$memcache_obj->connect(MEM_HOST, MEM_PORT);

array_shift($argv);
$command = array_shift($argv);

switch ($command) {
  case 'get':
    $keys = $argv;
    
    $re = $memcache_obj->get($keys);
    break;

  case 'get_list':
    $re = getKeyList($memcache_obj);
    break;

  case 'set':
    $keys = array_shift($argv);
    $value = array_shift($argv);
    
    $re = $memcache_obj->set($keys, $value);
    break;

  case 'delete':
    $keys = array_shift($argv);
    
    $re = $memcache_obj->delete($keys);
    break;

  default:
    showUsage();
    break;
}

$output[] = '==============================';
$output[] = 'command:' . $command;
if (is_array($keys)) $keys = join(',', $keys);
if ($keys)  $output[] = 'key(s):' . $keys;
if ($value) $output[] = 'value:' . $value;
$output[] = '==============================';
$output[] = '';

echo join("\n", $output);

if (is_array($re)) var_dump($re);
else echo $re;
echo "\n";


function showUsage() {

  $usage = basename(__FILE__) . " -- Usage >>>>\n";
  $usage.= "    :get_list\n";
  $usage.= "    :get [key1] [key2] [key3] ...  [keyN]\n";
  $usage.= "    :set [key] [value]\n";
  $usage.= "    :delete [key]\n";

  echo $usage;

}


/**
 * 統計情報からすべてのキーを抜き出す
 */
function getKeyList($memcache_obj) {
  $result = array();
  $tmp_keys = array();
  $all_keys = array();
  $total = 0;
  $old_total = 0;

  $slabs = $memcache_obj->getExtendedStats('slabs');

  $stats = $memcache_obj->getStats();
  $memcached_started_time = $stats['time'] - $stats['uptime'];

  $stats_item = $memcache_obj->getStats('items');
  $items = $stats_item['items'];
  foreach ($items as $slabclass => $item) {
      $stats_cachedump = $memcache_obj->getStats('cachedump', $slabclass, $item['number']);
      $tmp_keys = array_merge($tmp_keys, $stats_cachedump);
  }

  ksort($tmp_keys);
  foreach ($tmp_keys as $cache_key => $v) {
    $size = (int)$v[0];
    $time = ($v[1] == $memcached_started_time)? 0: $v[1];
    $expire = (!$time)? $time: date('Y/m/d H:i:s', $time);
    $old_flg = ($time && $time < time())? '*': ' ';
    $total+=$size;
    if ($old_flg == '*') $old_total+=$size;
    $all_keys[] = 'expire = ' . $expire . $old_flg . ' | size = ' . sprintf("%8s", $size) . ' | cache_key = ' . $cache_key;
  }



  $result[] = '* = old cache';
  $result[] = '--------------- ';
  $result[] = join("\n", $all_keys);
  $result[] = '--------------- ';
  $result[] = 'key count:' . count($all_keys);
  $result[] = '     total cache size:' . sprintf("%10s", $total) . 'byte';
  $result[] = '*old total cache size:' . sprintf("%10s", $old_total) . 'byte';

  return join("\n", $result);
}

2012/05/30

file_get_contentsで外部ファイルを読み取る


file_get_contentsで、外部のXMLや画像、webページなどを取得できる

◎普通に取得する場合
$homepage = file_get_contents('http://www.example.com/');
echo $homepage;

◎ファイルの一部の読み込み
// 21 文字目から 14 文字ぶん読み込みます
$section = file_get_contents('./people.txt', NULL, NULL, 20, 14);
var_dump($section);

◎Basic認証
file_get_contents("http://user:password@www.example.com/");

◎ストリームコンテキストの使用
・ストリームコンテキストでのBasic認証
// ストリームを作成します
$opts = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>"Authorization: Basic " .base64_encode("user:password"). "\r\n"
  )
// 上で設定した HTTP ヘッダを使用してファイルをオープンします
$file = file_get_contents('http://www.example.com/', false, stream_context_create($opts));

・特定のヘッダで送信
// ストリームを作成します
$header = Array(
  "Content-Type: application/x-www-form-urlencoded",
  "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
  "Accept-language: en",
  "Cookie: foo=bar"
);
$opts = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>join("\r\n", $header),
  )
);

$context = stream_context_create($opts);

// 上で設定した HTTP ヘッダを使用してファイルをオープンします
$file = file_get_contents('http://www.example.com/', false, $context);

◎POSTで送信
$data = array(
    'param1' => 'hoge',
    'param2' => 'hogehoge',
);
$opt = array('http' => array(
    'method' => 'POST',
    'content' => http_build_query($data),
));
$contents = file_get_contents('http://www.example.com/', false, stream_context_create($opt));



2012/05/27

今更ながら Cakeを焼く


cakeコマンドは coreの中のcake/console/cake (←shell)をbashで叩く
 →たたかれると 単に 同ディレクトリの cake.phpが呼ばれるだけ
これでうまくいかないなら
直接 php -q cake.php を叩けばいい
 ※ただ 上記のbashを利用すると自動でphpコマンドに「 -working」オプションをつけてくれるけどね カレントディレクトリが入るっぽい
■appをビルドする
cake bake
 →app アプリ一式をべべーっと作ってくれます
■各Controllerとか つくる
 ↑で作成した appディレクトリに行って
 cake bakeを叩くと なにつくるかーって聞かれます
$app>cake bake
Welcome to CakePHP v1.3.6 Console
---------------------------------------------------------------
App : app
Path: /hoge/huga/app
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[F]ixture
[T]est case
[Q]uit
What would you like to Bake? (D/M/V/C/P/F/T/Q)
 Controllerなら[C]すかね?
 そっからの参考は→こちら
手順的な流れは M→C→V かな



2012/05/24

HTTPレスポンス ヘッダー Content-type


CIは デフォルトだと、Content-typeのcharsetが設定されていない
LiveHTTPHeaders で確認↓
HTTP/1.1 200 OK
Date: Thu, 05 May 2011 07:19:18 GMT
Server: Apache
X-Powered-By: PHP/5.3.5
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 977
Content-Type: text/html
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
これは セキュリティ上よろしくないので設定する
方法的には hookのpost_controllerでフックとかあるけど、
取り敢えず今回は コントローラの頭でやりゃーいいんじゃねーかと思ったので
コントローラー拡張クラス(いわゆるMY_Controller)のコンストラクタに↓下記をぺろっと追加
$this->output->set_header('Content-Type: text/html; charset=UTF-8');
で、確認↓
HTTP/1.1 200 OK
Date: Thu, 05 May 2011 07:28:49 GMT
Server: Apache
X-Powered-By: PHP/5.3.5
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 977
Content-Type: text/html; charset=UTF-8
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
今後、なにやら細かい設定がしたくなったら 設定は別クラス作って フックでもいいかと思う
参考)




URLヘルパ


app/config/autoload.php
Auto-load Helperに設定
$autoload['helper'] = array('url');
※各コントローラで指定するなら、
$this->load->helper('url');
css絶対パスで指定(view内)
<link rel="stylesheet" href="<?=base_url()?>css/init.css" type="text/css" />

参考)
URL ヘルパ : CodeIgniter ユーザガイド 日本語版http://codeigniter.jp/user_guide_ja/helpers/url_helper.html
ヘルパ関数 : CodeIgniter ユーザガイド 日本語版http://codeigniter.jp/user_guide_ja/general/helpers.html




共通ヘッダー フッター(HTML) →その後


結局 hookは諦めて、Controllerを拡張して、loadクラスの なんちゃってview()みたいなのを作って落ち着いた。
動的に、headerのtitleを変えるにはこれしかなかったにょん(´・ω・`)ガッカリ…
app/core/MY_Controller.php
<?php if ( ! defined('BASEPATH')) exit('No direct script accessallowed');
class MY_Controller extends CI_Controller {
  private $vars = array();

  /**
   * Constructor
   */
  public function __construct()
  {
    parent::__construct();
  }

  /**
   * set vars
   * @access public
   * @param  $key  string
   * @param  $val  string
   * @return 
   */
  public function setVars($key, $val)
  {
    $this->vars[$key] = $val;
  }

  /**
   * set views
   * @access public
   * @param  $view  mixed
   * @param  $return bool
   * @return void
   */
  public function setView($view, $return = FALSE)
  {
    // common header
    $this->load->view('parts/header', $this->vars);
    if (is_array($view))
    {
      foreach ($view as $k) $this->load->view($k, $this->vars);
    }
    else
    {
      $this->load->view($view, $this->vars);
    }
    // common footer
    $this->load->view('parts/footer', $this->vars);
  }
}
app/views/parts/header.php
…略
<title>My Site Title - <?=$title?></title>
…略
・呼び出しコントローラ
app/controllers/hoge.php
<?php if ( ! defined('BASEPATH')) exit('No direct script accessallowed');
class Hoge extends MY_Controller {

  /**
   * list
   */
  public function list()
  {
    $this->setVars('title', 'HOGE LIST');
    $this->setView('hoge/list');
  }

  /**
   * edit
   */
  public function edit()
  {
    $this->setVars('title', 'HOGE EDIT');
    $this->setView('hoge/edit');
  }
}




共通ヘッダー フッター(HTML)


要するに、CakePHPで言う、layoutみたいなことがやりたいわけだ
サイトのページで共通する ヘッダー部分とか フッター部分は どこか1箇所に書きたい
本家のやり方は、結局Controllerに毎回 header footerを書かなきゃならないから、だめじゃん?
ビュー : CodeIgniter ユーザガイド 日本語版http://codeigniter.jp/user_guide_ja/general/views.html
→複数のビューの読み込み
・hookを使ってみる
CIにはviewクラス的なものがないから、cakeコントローラのCallbackメソッド(beforeFilterとかafterFilterとか)的なものを探したら、hookがそれにあたる(?)ぽいので、やってみる
※app/は 自前アプリケーションフォルダ index.phpで指定する$application_folder
・共通ヘッダー&フッターを作成(View)
app/views/parts_hook
      ┠ header.php
      ┗ footer.php
※それぞれ HTMLのヘッダー部分とフッター部分
・自前hookクラスを用意
app/hooks/ControllerCallback.php
/**
* ControllerCallback Class
*/
class ControllerCallback {
  /**
   * beforeFilter - post_controller_constructor
   */
  public function beforeFilter()
  {
    // 共通ヘッダー
    $ci =& get_instance();
    $ci->load->view('parts_hook/header');
  }
  /**
   * afterFilter - post_controller
   */
  public function afterFilter()
  {
    // 共通フッター
    $ci =& get_instance();
    $ci->load->view('parts_hook/footer');
  }
}
・hook設定
app/config/hooks.php
/*
| --------------------------------------
| Hooks
| --------------------------------------
| This file lets you define "hooks" …略
$hook['post_controller_constructor'] = array(
                'class'  => 'ControllerCallback',
                'function' => 'beforeFilter',
                'filename' => 'ControllerCallback.php',
                'filepath' => 'hooks'
                );

$hook['post_controller'] = array(
                'class'  => 'ControllerCallback',
                'function' => 'afterFilter',
                'filename' => 'ControllerCallback.php',
                'filepath' => 'hooks'
                );
※最初、beforeFilter()をpre_controllerで呼んだら、コントローラインスタンス化される前だから駄目だった(汗
※'params'は使ってない
参考)
フック : CodeIgniter ユーザガイド 日本語版http://codeigniter.jp/user_guide_ja/general/hooks.html

これで、共通ヘッダーとフッターは表示された
うーんでも、これだと、ヘッダーの中の<title>とかを動的に設定したい(各コントローラーで指定したい)ときに、だめだなあ…
ということで、続く





コアクラスの拡張 ~Logクラス


・本体からコピって自分とこのappに置く(拡張prefix付ける MY_とか)
  system/libraries/Log.php → application/core/MY_Log.php
・なんでLogクラスってコアのくせにlibrariesにあるわけ?
  →とか思いながら、リファレンス通りにapplication/core/配下においても動かねーし。
  →やっぱり、
  system/core/→application/core/
  system/libraries/→application/libraries/
  で、いいらしい。
・ログファイル名もconfig/config.phpで設定できるようにしたい
  →config/config.phpに $config['log_file_name'] = 'app.example.log';追加
  →MY_Log::__construct()処理追加
public function __construct()
{
  parent::__construct();
  $this->_log_file_name = date('Y-m-d').EXT;←CIデフォルト
  $config =& get_config();
  if ($config['log_file_name'] != '')
  {
    $this->_log_file_name = $config['log_file_name'];
  }
}
・ログのレコードフォーマットが気にくわないから変える
  →MY_Log::write_log()編集
public function write_log($level = 'error', $msg, $php_error = FALSE)
{
  if ($this->_enabled === FALSE)
  {
    return FALSE;
  }
  $level = strtoupper($level);
  if ( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold))
  {
    return FALSE;
  }
  $filepath = $this->_log_path.$this->_log_file_name;
  $message = '';
  if ( ! $fp = @fopen($filepath, FOPEN_WRITE_CREATE))
  {
    return FALSE;
  }
  $message .= date($this->_date_fmt).' ('.$level.') '.$msg."\n";
  flock($fp, LOCK_EX);
  fwrite($fp, $message);
  flock($fp, LOCK_UN);
  fclose($fp);
  @chmod($filepath, FILE_WRITE_MODE);
  return TRUE;
}
参考)
コアシステムクラスの作成 : CodeIgniter ユーザガイド 日本語版
ヌル日記




CodeIgniter ~まずすることめも


application/
・名前をapp/(そのままでもいいし)に変えて、web_rootとは別のとこに置く(system/とも別のとこ)
index.php
・web_rootに置く
・$system_path $application_folderのパス設定
app/config/config.php
・$config['base_url'](設定しなくてもいいらしいが?)
・$config['index_page'] = '';
  →mod_rewriteを使って「index.php」を URIから抹殺する時は、ここは空('')のままで。
・$config['url_suffix'] = '.html';
  →.htmlをつけてアクセスできる 見せかける
・$config['charset'] = 'UTF-8';
・$config['enable_hooks'] = FALSE; ←フック使わなきゃFALSE
・$config['subclass_prefix'] = 'MY_';
  →今は未設定 そのうち使うかも
・$config['log_threshold']=0
  →ログを出すときは下記の設定から選ぶ
  →0だとログでない
| 0 = Disables logging, Error logging TURNED OFF
| 1 = Error Messages (including PHP errors)
| 2 = Debug Messages
| 3 = Informational Messages
| 4 = All Messages
・$config['log_path'] →ログ出す場所 フルパス
  →ログファイル名まで書くのかと勘違いしてた...orz
  →ログディレクトリパスを書く ex)$config['log_path'] = 'C:/webapp/logs/';
  →win環境で、¥使うとエラーになるから/スラッシュで。
  →指定しなければ、デフォルトのAPPPATH.'logs/'が指定される
・$config['encryption_key'] セッション使うなら
・Session Variables →セッションの詳細設定
Cookie Related Variables →cookie詳細設定
・Cross Site Request Forgery →このへんも必要かも(未設定)
app/config/autoload.php
DBをapp全体で使うなら
$autoload['libraries'] = array('database');
  →使いたいところで接続する手動設定とか、DSN設定とかも使えるし
app/config/database.php
DB設定
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'username';
$db['default']['password'] = 'password';
$db['default']['database'] = 'test';
とか
$db['default']['dbcollat'] = 'utf8_general_ci';
とかね
app/config/routes.php
・$route['default_controller'] →デフォルトコントローラ
デフォルトのCodeIgniterのURI
example.com/index.php/class/function/ID
 →デフォルトコントローラは、index.phpなくてもいいくせに…(# ゚Д゚)
↑このindex.phpを 消すためにRewrite設定
・web_root配下に .htaccess設置(もしくはhttpd.confでもいいけど)
・↓設定
RewriteEngine on
RewriteCond $1 !^(index\.php|robots\.txt|.+\.css$|.+\.js$|.+\.png$|.+\.gif$)
RewriteRule ^(.*)$ index.php/$1 [L]
※この設定では「index.php」「robots.txt」で始まるリクエスト、もしくは「.css、.js、.png、.gif」で終わるリクエスト以外
データベースへの接続 : CodeIgniter ユーザガイド 日本語版