ITエンジニア志望なら最初はインフラ系がおすすめ

 ITエンジニアと言っても、色々な立ち位置がある。システムエンジニアプログラマー、ネットワークエンジニア、サーバーエンジニア、DBエンジニア・・・。僕は個人的には、ネットワーク・サーバーエンジニア、次点でDBエンジニアをおすすめしたい。いわゆるインフラ系といわれる分野である。かくいう僕はシステムエンジニアプログラマ寄り、いわゆるアプリ系のエンジニアである。

アプリ系は競争が激しい

 アプリ界隈というのは非常に競争が激しい。参入障壁があまりにも低いからである。PCさえあれば、低スペックでも便利なエディタをインストールして、すぐにプログラミングを始めることができる。最近では、家事の片手間にスマホアプリ開発をする主婦までいるそうだ。競争が激しい=扱っている人が大勢である故に、技術の進歩・・・というか流行り廃りが激しい

javascriptであれば、やれAngularだ、Reactだ、jqueryはダサいだ、CoffeeScriptがなんだ、TypeScriptがなんだ。PHPであれば、fuelがなんだ、CakePHPがなんだ、最近はLaravelとSymfonyの2強だなんだかんだかんだあんだああああああ!!??読み易くて動けば何でもいいじゃねえか!!一々新しいもん作ってんじゃねええええ!・・・とか思ってしまう、僕のようなダメエンジニアが生まれるのも納得なミーハー具合である。

そして、そういうスピード感に何のストレスもなく付いて行き、尚且つコンピューターそのものに対する理解もずば抜けているような、基地外という他ないエンジニアも、この界隈には多いのである。知能・好奇心・ITに対する興味などを含め、初期スペックが我々と全く違うと言ってよい。それがアプリ系エンジニアの難しさである。

もっとも、数学や統計学が得意でデータサイエンス的な分野を扱えるとか、特に難しいアルゴリズムを実装できるとか・・・僕には想像もつかない分野であるが、そういった別の専門性を有しているのであれば、また別の話かもしれない。

インフラ系は参入障壁が高い

 今はレンタルサーバーもあるし、クラウドもある。インフラ系だって誰でも弄れる時代だ。なんて思うかもしれないが、レンタルサーバーなどの環境を借りるのには、やはりお金がかかる。大抵は月額費用であり、一般人からすると大きな障害になる。無料のレンタルサーバーも存在するし、個人で扱う分には概ね事足るが、そこで出来ることなどエンジニアというレベルではたかが知れている。

個人でLinuxベースのサーバーを借りてWebを公開、なんてこともできるが、特に難しいことは何もない。単にWebサーバーを立てて、そこにCGIを置き、DBを立て、SSHを有効にし、SSLの設定をして、セキュリティ周りを一通り確認して、公開するだけ。Google先生と少しばかりの書籍から習得できる。個人でやるのはそのレベルである。

サーバーの冗長化、ネットワークの構築、DBのチューニング等々のお話は、よほどデカいサービスにでも育たたなければ考える必要もない。しかし職業エンジニアとなった時点で、そういう考え方は必須になる。つまり非エンジニアとエンジニアで明確な差ができる部分なのである。

インフラから入った方が効率が良い

 スマホ界隈については知らないが、業務システム開発にせよ、Webサービス開発にせよ、アプリ開発をしていれば、HTTPを含めたTCP/IPやデータベースといったインフラ、ミドルウェア寄りの要素を確実に扱うことになるだろう。こういった時、より低レイヤ―のことを先に理解しておいた方が、往々にしてアプリなどの高レイヤー技術は理解しやすいものである。

 僕が会社に入って一番最初に携わったのは、Oracleというデータベースと頻繁に通信するアプリケーションの開発であったが、tnsnames.oraの中身が何を意味するのかしっくりこなかった(tnsnames.oraとは、ざっくり言うとPCからoracleサーバーへ接続するための、接続情報が記されたファイルである。)。それも結構長い間である。ググれば出てくるし、言葉はわかるのだが、しっくりこない。理由は単純で、TCP/IPに対する理解が無いからであった。TCP/IPという決まりの中で、データーがどういう風に流れるのか、イメージができなかったのである。

あまりに分からないので、マスタリングTCP/IPという、ネットワーク初学者のバイブル的な本を読んだり、データべースに関してまとめられた専門的なサイトを梯子したりして、インプットに努めた時期もあった。そうしてようやく、プログラミングの中でやっている外部的なデータの流れがイメージできるようになったのである(あくまでも最低限の知識ではあるが)。

逆に言うと、低レイヤの知識を先に突っ込んでしまえば、プログラミングなどをする上での障害が取り除かれやすくなり、効率的に学ぶことができる。なお、ここでインフラと呼んでいる分野も、データ処理の話であるため、結局はアプリケーション(C言語などによって実装される)の話になってくるのであるが、それはより専門的な方々に任せておけばよいと思う。

最終的に広い知識が必要

 インフラとアプリを区別してきたが、近年はインフラとアプリの距離がグッと近づいてきている。仮想化技術、クラウドの発達によって、難解な設定をせずとも、GUIでポチポチやればサーバーやネットワークを立てられる時代になってきた。アプリケーションも同様に、開発効率の上がる仕組みがどんどん出来上がってきている。

こういった状況を突き詰めると、一人当たりの生産力が非常に高くなる。一人でインフラの構築からアプリの開発・連携まで出来るようになるということである。それは専門性が浅くなるというわけではない。より優れた開発・運用にあたって、アプリ・インフラ双方の知識が深く必要になるということだと考えている。具体的に言えば、整頓された保守性の高いコードを高速に書く力と、インフラ技術に対する(構築技術ではなく)体系的な知識・経験であると思っている。

長くなってしまったが、ITエンジニアを志望しており、貴方が特段別の専門性(特に理系的な)を有しておらず、アプリ系(プログラミング)かインフラ系か迷っているorどちらでもいいと思っているのであれば、インフラ系から入ることをお勧めしておこうと思う。

SDKを使ってPHPでDropBoxのAPIを扱う

 個人で作っていたWebアプリを久々に見ていたら、ファイル関連でうまく動作していないことに気が付き、調べてみると、どうやらDropBoxAPIがバージョンアップした影響のようでした。というわけで今まで使っていたSDKは使えないようです。

旧バージョン対応のSDKというのはこれです。

github.com

新バージョン対応のSDKはこちら。サムネイルが僕並のイケメンですね。

github.com

どちらも有志ですね。すごいなあ。

とまあそういうわけで、新しいSDKを用いたラッパークラスを作ってみました。

<?php
//このプログラムは kunalvarma05/dropbox-php-sdk を用いて、
//PHPでDropBoxを扱うためのラッパークラスです。
//参考:https://github.com/kunalvarma05/dropbox-php-sdk
use Kunnu\Dropbox\Dropbox;
use Kunnu\Dropbox\DropboxApp;
use Kunnu\Dropbox\DropboxFile;
use Kunnu\Dropbox\Exception;
class OperateDropbox{
    private $accessToken = 'your-DropBox-APPs-AccessToken';
    private $key = 'your-DropBox-APPKey';
    Private $secret = 'your-DropBox-APPsecret';
    private $dropbox;  
 
    //DropBoxに接続するクライアント作成
    public function MakeClient(){
        $app = new DropboxApp($this->key,
            $this->secret, $this->accessToken);
        $this->dropbox = new Dropbox($app);
    }
    
    //DropBoxにファイル保存
    public function UploadToDropBox($filePathOnDropBox, $filePathOnLocal){
        try{
            $dropboxFile = new DropboxFile($filePathOnLocal);
            $file = $this->dropbox->upload($dropboxFile,
                $filePathOnDropBox, ['autorename' => true]);
            return true;
        }catch(DropboxClientException $ex){
            return false;
        }
    }
    
    //Dropboxからファイルをダウンロード
    public function DownLoadToLocal($filePathOnDropBox, $filePathOnLocal){
        try{
            $file = $this->dropbox->download($filePathOnDropBox);
            $content = $file->getContents();
            file_put_contents($filePathOnLocal, $content);
            $metadata = $file->getMetadata();
            $metadata->getName();
            return true;
        }catch(DropboxClientException $ex){
            return false;
        }
    }
    
    //Dropboxからファイル削除
    public function DeleteFromDropBox($filePathOnDropBox){
        try{
            $res = $this->dropbox->delete($filePathOnDropBox);
            return true;
        }catch(DropboxClientException $ex){
            return false;
        }
    }
}


$operateDropBox = new OperateDropbox();
$operateDropBox->MakeClient();
$operateDropBox->anyFunction();

?>

アップロード、ダウンロード、削除っていう基本機能ですが、よかったらぜひ使ってみてください。何か間違っていたらご指摘いただけると嬉しいです。

Gistはこちら→DropBoxWrapper.php · GitHub

SDKを使ってPHPでLINE Messaging APIを扱う

僕がおもちゃの開発で使っているラッパークラスです。

<?php
//LINEMessagingAPIに接続するラッパークラスです。
//line/line-bot-sdk-php を利用しています。
//参考:https://github.com/line/line-bot-sdk-php
class LineMessage {
    private $httpClient;
    private $bot;
    private $channelAccessToken = 'your-channel-acccessToken';
    private $channelSecret = 'your-channel-acccessSecret'
    
    //LINEMessagingAPI接続用クライアントの作成
    public function MakeClient(){
        $this->httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient($this->channelAccessToken);
    }
    
    //LINE BOTのオブジェクト作成
    public function MakeBot(){
        $this->bot = new \LINE\LINEBot($this->httpClient, ['channelSecret' => $this->channelSecret]);
    }
    
    //テキストメッセージのオブジェクト作成
    public function MakeMessageBuilder($strRetrunMessage){
        $textMessageBuilder = new \LINE\LINEBot\MessageBuilder\TextMessageBuilder($retrunMessage);
        return $textMessageBuilder;
    }
    
    //テキストメッセージ送信&結果を受信
    public function MakeMessageResponse($retrunMessage, $replyToken){
        $r_message =  $this->MakeMessageBuilder($retrunMessage);
        $response = $this->bot->replyMessage($replyToken, $r_message);
        return $response;
    }
}


$lineMessage = new LineMessage();
$lineMessage->MakeClient();
$lineMessage->MakeBot();
$objReturnMessage = $lineMessage->MakeMessageBuilder($strReturnMessage);
$lineMessage->MakeMessageResponse($objReturnMessage, $replyToken);

?>

↓ここで作られているSDKをラッピング(語源合ってるのかな)したものです。 

github.com

これも恐らく有志ですね。趣味でやる分にはどんどん使っちゃいましょう。僕のクラスはメッセージ返しているだけですが、画像や選択ボックスを返したりなど、もっと色々な機能があります。僕の方でも(ラッパークラスを)どんどん拡張していきたいと思います。

Gistはこちら→LINEMessaginAPIWrapper.php · GitHub

PHPで特定のサイトのスクリーンショットを取る

PHP PhantomjsというGit-Hubで公開されているライブラリを使って、スクリーンショットを取るためのラッパークラスを作りました。

github.com

↑がGitHubリポジトリのリンクです。サムネイルはダンディーなおじさまですね。

<?php
//phantomjsを使って特定のWebサイトのスクショを取って保存するクラスです。
//jonnnnyw/php-phantomjs のラッパー?ラッピング?したものです。
//参考:https://github.com/jonnnnyw/php-phantomjs

use \JonnyW\PhantomJs\Client;
class ScreenShot{
    private $client;
    private $request;
    private $response;
    private $width;
    private $height;
    private $top;
    private $left;
    private $URL;
    private $timeOut = 30000;
    
    //画面サイズなどを決定する
    function __construct($width, $height, $URL){
        $this->width = $width;
        $this->height = $height;
        $this->top = 0;
        $this->left = 0;
        $this->URL = $URL;
    }
    
    //phantomjs実行クライアントを作成する
    public function MakeClient(){
        $this->client = Client::getInstance();
        $this->client->isLazy(); //ページのレンダリング待ち
        $this->client->getEngine()->setPath(__DIR__ . '/../bin/phantomjs');
    }
    
    //スクショリクエストの詳細を設定する
    //ここでは、ブラウザサイズと同じ範囲を撮影範囲としている
    public function MakeRequest($screenshotFileName){
        $this->request = $this->client->getMessageFactory()->createCaptureRequest($this->URL, 'GET');
        $this->request->setTimeout($this->timeOut); //強制的に終了するまでの時間
        $this->request->setOutputFile($screenshotFileName); //スクショのファイル名
        $this->request->setViewportSize($this->width, $this->height); //ブラウザサイズ
        $this->request->setCaptureDimensions($this->width, $this->height, $this->top, $this->left); //撮影範囲
    }
    
    //リクエストのレスポンス(の受け皿)を作成する
    public function MakeRespose(){
        $this->response = $this->client->getMessageFactory()->createResponse();
    }
    
    //リクエストを送信する
    public function SendRequset(){
        $this->client->send($this->request, $this->response);
    }
    
    //
    public function MakeImg($screenshotFileName){
        $this->MakeClient();
        $this->MakeRequest($screenshotFileName);
        $this->MakeRespose();
        $this->SendRequset();
        //ファイルサイズ 0 byte = 画面取得できてないと判断
        If(filesize($ssName) != 0){
            return true;
        }else{
            return false;
        }
    }
}


//yahooのトップをブラウザの横幅を1000として撮影し、
//screenshot.jpgというファイルに保存する。
$screenshot = new ScreenShot(1000, 750, 'https://www.yahoo.co.jp/'); 
$screenshot->MakeImg('screenshot.jpg'); 

?>

まとめサイトのサムネイル自動生成なんかに使えると思います。というか使っています。ライブラリの名前通り、裏ではPHPがphantomjsを使って対象のサイトを表示し、スクリーンショットを撮影しています。

ちなみにphantomjsというのは、ヘッドレスブラウザという、GUIの無いブラウザの1つです。見た目上は対象サイトを表示しませんが、裏ではブラウジングしており、javascriptで動作を制御することができます。

このライブラリはphpjavascriptのコードを自動生成し、それによってphantomjsを操作しているわけです。よう作りますなあ。ちなみに、jpgやpngだけでなく、pdfでの出力も可能です。もちろん、スクレイピングにも利用できます。

Gistはこちら→ScreenShot.php · GitHub