phpの関数の大文字小文字の区別

これをみて欲しいんですが、、、

<?php
function userLog(){
    echo "log書いたよ!";
}

UserLog();

みたいなコードが本番コードにあって
関数名が違う!ログ取れてなくねっとなって調べてみましたが、
ちゃんと関数を呼べてるようです。

調べてみると、
phpは変数は大文字小文字を区別しますが、
関数名は大文字小文字を区別しないようです。

これは知らないと何か起きそうですね。。。

地味に使えそうなcatをクリップボードに流し込む方法

terminalで作業していてそれをブログに貼りたい時とか困りますよね?

そういう時は
pbcopy
を使いましょう。

cat memo.txt | pbcopy

クリップボードにコピーされるので
ctrl + vでどこにでも貼れますね!

qiita.com
(ありがとうございました)

lispで8クイーン実装して見た

最近common lispに入門しようとして頑張っているのですが、
lispはすごく楽しいですね!
かっこの中に処理がハマった時にテトリスのような快感がありますね。

(defclass queen ()
  ( num
    count
    result))

(defmethod init ((q queen) n)
  (setf (slot-value q 'num) n)
  (setf (slot-value q 'count) 0)
  (setf (slot-value q 'result) nil)
  (let ((i 0))
    (loop
      (push 'nil (slot-value q 'result))
      (setf i (+ i 1))
      (when (>= i n) (return)))))

(defmethod run ((q queen) y)
  (let ((x 0))
    (loop
      (init_array q y)
      (when (can_put q x y)
        (progn
          (put q x y)
          (if (>=  y (- (slot-value q 'num) 1))
              (progn
                (setf (slot-value q 'count) (+ (slot-value q 'count) 1))
                (write_field q))
              (run q (+ y 1))) ) )
      (setf x (+ x 1))
      (when (>= x (slot-value q 'num)) (return))))
  nil)

(defmethod init_array ((q queen) y)
  (let ((i 0))
    (loop
      (when (>= i y)
        (setf (nth i (slot-value q 'result)) nil))
      (setf i (+ i 1))
      (when (>= i (slot-value q 'num)) (return)))))

(defmethod can_put ((q queen) x y)
  (if (and (null (nth y (slot-value q 'result)))
           (null (is_include q x))
           (slant_check q x y))
      t
      nil))

(defmethod slant_check ((q queen) x y)
  (let ((tmp1 (- y x))
        (tmp2 (+ y x))
        (i 0)
        (tmp t))
    (loop
      (when (and (not (null (nth i (slot-value q 'result))))
                 (or (= i (+ (nth i (slot-value q 'result))  tmp1)) (= i (+ (* (nth i (slot-value q 'result))  -1) tmp2))))
        (setf tmp nil))
      (setf i (+ i 1))
      (when (>= i (slot-value q 'num)) (return)))
    tmp ))

(defmethod write_field ((q queen))
  (let ((i 0)
        (j 0))
    (loop
      (setf j 0 )
      (loop
        (if (and (not (null (nth i (slot-value q 'result))))
                 (= (nth i (slot-value q 'result)) j))
            (princ "Q ")
            (princ "_ "))
        (setf j (+ j 1))
        (when (>= j (slot-value q 'num)) (return)))
      (terpri)
      (setf i (+ i 1))
      (when (>= i (slot-value q 'num)) (return)))
    (print (slot-value q 'count))
    (terpri)))

(defmethod is_include ((q queen) x)
  (let ((i 0)
        (tmp nil))
    (loop
      (when (and (not (null (nth i (slot-value q 'result))))
                 (= (nth i (slot-value q 'result)) x))
        (setf tmp t))
      (setf i (+ i 1))
      (when (>= i (slot-value q 'num)) (return)))
    tmp ))

(defmethod put ((q queen) x y)
  (setf (nth y (slot-value q 'result)) x))


(defun main ()
  (let ((qu (make-instance 'queen)))
    (init qu 8)
    (run qu 0)))

(main)

マクロとかはまだわからないし、
クラスのメンバにアクセスできるもう少し綺麗な書き方とかあるかもしれないですけど、
とりあえず動いたことがとても嬉しいですね!

lispのS式を書いていると、
日本人は英語できるようになったり、するんでしょうか?
全然英語できないですが、関数を頭に持ってくる感じが
動詞を前に持ってくるのと似ているような気がします笑

※Rustでも描きたいけど型の厳密さが難しい

phpで使いそうな画像処理のクラス

phpで画像縮尺とか
exifで回転させたい時とかあると思います。

その時のために画像処理のクラスを作ってメモがてら貼っておきます。
次使う時にデバックするのでまだテストしていません。(すみません)

デバッグしてなさすぎ動かない!また上げ直します。)
(こっちみてください -> http://pascal-tongue.hatenablog.com/entry/2017/10/12/140459

<?php
class ImageChanger{
      const FILE_MAX_LENGTH = 750; //画像の縮小時の長い方の長さ
      const COMPRESSION = 60;

      private $target_file;
      private $width;
      private $height;
      private $type;

      function __construct($_image = ""){
            $this->image = $image;
      }

      //画像の縮小
      public function image_create(){ //->bool
            if(!$this->file_exists()) return false;
            $this->get_image_information();
            $size = $this->imageSize(self::FILE_MAX_LENGTH);

            //型作り
            $new_image = imagecreatetruecolor($size['width'], $size['height']);

            switch($type){
            case 'image/gif':
                  $base_image = imagecreatefromgif($this->target_file);
                  break;
            case 'image/png':
                  $base_image = imagecreatefrompng($this->target_file);
                  break;
            case 'image/jpeg':
            case 'image/jpg':
                  $base_image = imagecreatefromjpeg($this->target_file);
                  break;
            default:
                  return false;

            }
            //型に合わせて作成
            imagecopyresampled($new_image, $base_image, 0, 0, 0, 0, $size['width'], $size['height'],  $w, $h);
            ImageDestroy($base_image);

            //元データの削除
            if(file_exists($this->image)){
                  $this->image = "";
                  unlink($this->image);
            }
            $file_path = $this->get_new_image_path();

            imagejpeg($new_image, $file_path, self::COMPRESSION);
            ImageDestroy($new_image);

            $this->image = $file_path;
            return true;
      }


      //画像の向きを元に戻す
      public function image_rotate(){ //->bool
            if(!$this->file_exists()) return false;
            $this->get_image_information();

            if($this->type != "image/jpeg" && $this->type != "image/jpg"){
                  return false;
            }
            //型作り
            $new_image = imagecreatetruecolor($this->width, $this->height);

            $exif = $this->exifInformation($pre_file);
            if($exif == null) return;

            $base_image = imagecreatefromjpeg($this->image);
            if(isset($exif['IFD0']['Orientation'])){
                  //回転処理
                  $rotate_infos = $this->imageRotation($exif['IFD0']['Orientation']);

                  //反転
                  if(!empty($rotate_infos['mode'])){
                        $base_image = imageflip($base_image, $rotate_infos['mode']);
                  }

                  //回転
                  if($rotate_infos['degrees'] > 0){
                        $base_image = imagerotate($base_image, $rotate_infos['degrees'], 0);
                  }
            }

            //元データの削除
            if(file_exists($this->image)){
                  $this->image = "";
                  unlink($this->image);
            }
            $file_path = $this->get_new_image_path();

            imagejpeg($base_image, $file_path, self::COMPRESSION);
            ImageDestroy($base_image);

            $this->image = $file_path;
            return true;
      }

      //exif情報取得
      public function exif_information($filepath){
            if(!$this->file_exists()) return false;
            $exif = exif_read_data($file, 0, true);
            if($exif != false){
                  return null;
            }else{
                  return $exif;
            }
      }

      //同じ縦横比のまま長いほうが指定した数値になるように縦横を返す
      private function image_size($max_length){ // -> [int, int]
            if($this->width < $max_length || $this->height < $max_length){
                  $w = $this->width;
                  $h = $this->height;
            }elseif($this->width > $this->height){
                  $ratio = $this->width / $this->height;
                  $h = $max_length;
                  $w = round($height * $ratio);
            }elseif($w < $h){
                  $ratio = $this->height / $this->width;
                  $w = $max_length;
                  $h = round($w * $ratio);
            }else{
                  $w = $max_length;
                  $h = $max_length;
            }
            $size = ['width' => $w, 'height' => $h];
            return $size;
      }

      //イメージの回転修正
      //ファイルのパスをもらって回転の処理に必要な$mode, $degreesを返す
      private function image_rotation($exif){ //-> [string, int]
            if(isset($exif) == false){
                  return ["", 0];
            }
            $degrees = 0;
            $mode = '';

            switch($exif){
            case 1:
                  break;
            case 2:
                  $mode = 'IMG_FLIP_HORIZONTAL';
                  break;
            case 3:
                  $degrees = 180;
                  break;
            case 4:
                  $mode = 'IMG_FLIP_VERTICAL';
                  break;
            case 5:
                  $degrees = 90;
                  $mode = 'IMG_FLIP_HORIZONTAL';
                  break;
            case 6:
                  //$degrees = 90;
                  $degrees = 270;
                  break;
            case 7:
                  $degrees = 90;
                  $mode = 'IMG_FLIP_VERTICAL';
                  break;
            case 8:
                  $degrees = 270;
                  break;
            }

            return ['mode' => $mode, 'degrees' => $degrees];
      }
      //fileが存在しているか?
      private function file_exists(){ //-> bool
            $result = true;
            if(!isset($this->target_file)){
                  $result = false;
            } else if(!file_exists($pre_file)){
                  $result = false;
            }
            return $result;
      }

      private function get_new_image_path(){ // -> string
            $name = str_replace('.', '', microtime(true));
            $filepath = 'tmp/'. $name. '.jpeg';
            return $file_path;
      }
      //file 情報取得
      private function get_image_information(){ //->void
            $infos = getimagesize($this->target_file);
            $this->width = $infos[0];
            $this->height = $infos[1];
            $this->type = $infos['mime'];
      }
}

common lisp 入門して見た

今回はcommon lisp
1000までの素数表示させて見ました。

(defun main()
  (let ((i 2)(j 2))
    (loop
      (setq j 2)
      (loop
        (when (= j i)
          (print i)
          (return))
        (when (= (rem i j) 0)
          (return))
        (setq j (+ j 1)))
      (setq i (+ i 1))
      (when (= i 1000)
        (return)))))

(main)

こんな感じでいいんですかね?
lisp難しいけどなんか書き終わった後は謎の達成感がありますね!

最近いろんな言語勉強しすぎてます笑。
一つの言語で技術をあげることにも力を入れていきたいです。

javascriptで並行処理してみた。

こんにちは!


今日はjavascriptで 並行処理のworkerというものを使って見ました。

//並行処理呼び出し main.js
console.time(1);
var a = new Worker('a.js');
a.addEventListener('message',
      function(e) {
            console.log(e.data.testData);
            console.timeEnd(1);
      }, false);
//並行処理側 a.js
var global_scope = this.self;

var countNum = 0;
for(i=1;i<=5000000;i++){
		countNum++;
}
global_scope.postMessage({
	testData:countNum
});

これと同じ処理を三つ繋げて呼び出して見ましたが どのブラウザでも使えるようになればいいなと思いますね。 今はfirefoxぐらいでしか使えないのかな?

https://base.terrasky.co.jp/articles/anNmq (参考にさせていただきました。ありがとうございます!)

php facebook認証クラス作ってみた

業務でfacebookの認証をやることがありました。
元々はフレームワークの中に書いてしまっていたものなので
ほぼメモがわりのクラスです。
動作確認していません。
参考にしてくれるのはとてもうれしいのですが テストしていないのでご了承ください:)

<?php
 class Facebook{
	const APP_ID = "";
	const APP_SECRET = "";
	const STATE = "";
	const CALLBACK_URL = "";
	//facebookのログイン画面のリダイレクトURL取得
	public function redirectURL($scope = null){
		$callback_url = urlencode(self::CALLBACK_URL);
		$facebook_url =  "https://www.facebook.com/dialog/oauth?client_id=". self::APP_ID. "&redirect_uri=". $callback_url. "&state=". self::STATE. "&scope=". $scope;
		return $facebook_url;
	}
	//フェイスブックとの認証やユーザーの登録
	public function oauth($params){
		if($this->isCodeCorrect($params) == false) return false;
		if($this->isStateCorrect($params) == false) return false;
		$token_array = $this->accessToken($code);
		if($token_array == null) return false;
		$access_token = $token_array['access_token'];
		$user_array = $this->userGet($access_token);
		if($user_array == null) return;
		$result = $this->userCreate($user_array);
		return $result;
	}
	//codeが正しくきているのか?
	private function isCodeCorrect($params){
		//codeのついて確認
		if(isset($params['code'])){
			return true;
		}else if(isset($params['error_reason'])){
			echo $params['error_reason'];
			return false;
		}else{
			echo "Unexpected error";
			return false;
		}
	}
	//facebookに渡したstateが正しいかチェック
	private function isStateCorrect($params){
		if(isset($params['state'])){
			$state = str_replace('#_=_', '', $params['state']);
			if($state == self::STATE){
				return true;
			}else{
				echo "Unexpected error";
				return false;
			}
		}else{
			return false;
		}
	}
	//アクセストークンの取得
	private function accessToken($code){
		$get_token_url = "https://graph.facebook.com/v2.7/oauth/access_token?client_id=". self::APP_ID. "&redirect_uri=". self::CALLBACK_URL. "&client_secret=". self::APP_SECRET. "&code=${code}";
		if($get_token_json = file_get_contents($get_token_url)){
			$get_token_array = json_decode($get_token_json, true);
			return $get_token_array;
		}else{
			return null;
		}
	}
	//ユーザー情報の取得だけ
	private function userGet($access_token){
		$info_url = "https://graph.facebook.com/v2.7/me?fields=name,first_name,last_name,link&access_token=${access_token}";
		if($json = file_get_contents($info_url)){
			$user_array = json_decode($json, true);
			return $user_array;
		}else{
			return null;
		}
	}
	//ユーザー情報の登録
	private function userCreate($user_array){
		//DB登録処理
		return true; //or false
	}
}