php fopenの’rb’とは?

tmpファイルのアップロードで、以下の様に書いていた。

$image = fopen($_FILES['upfile']['tmp_name'],'rb');

ところで、この’rb’って何? 一瞬、rubyの拡張子に見えたんだが、絶対違うよな。。
‘b’は強制的にバイナリモードにします。
fopen(‘file’,’r’): 読み込みのみで開く。ファイルポインタはファイルの先頭におく。
fopen(‘file’,’r+’): 読み書き可能な状態で開く。ファイルポインタはファイルの先頭におく。
‘b’は強制的にバイナリモードにする。

よって fopen(‘file’,’r’); は、読み込みのみで開く。強制的にバイナリモードにする。

バイナリモードで開くってことね♪

phpでアップロードした画像のファイル名を取得しよう

まずformでアップロード機能をサクッと作ります。

<?php
if(file_exists($_FILES&#91;'upfile'&#93;&#91;'tmp_name'&#93;)){
	$ext = substr($_FILES&#91;'upfile'&#93;&#91;'name'&#93;, strrpos($_FILES&#91;'upfile'&#93;&#91;'name'&#93;,'.') + 1);
	echo $ext."<br>";
	if(strtolower($ext) !== 'png' && strtolower($ext) !== 'jpg' && strtolower($ext) !== 'jpeg' && strtolower($ext) !== 'gif'){
		echo '画像以外のファイルが指定されています。画像ファイル(png/jpg/jpeg/gif)を指定して下さい';
		exit();
	}

	$tmpname = str_replace('/tmp/', '', $_FILES['upfile']['tmp_name']);
	echo $tmpname;
	// $new_filename = 'profiles/'.$id.'-'.time().'-'.$tmpname.'.'.$ext;
}

?>
<div id="content">
<h2>画像管理</h2>
<hr>
<form action="#" method="POST" enctype="multipart/form-data">
<div id="drag-drop-area">
 <div class="drag-drop-inside">
  <p class="drag-drop-info">ここにファイルをアップロード</p>
  <p>または</p>
  <!-- <input type="file" value="ファイルを選択" name="image"> -->
  <p class="drag-drop-buttons"><input id="fileInput" type="file" value="ファイルを選択" name="upfile"></p>
      <input type="submit" value="送信">
   </div>
  </div>
</form>

アップロード前

アップロード後

うん、上手くいってるようです。
さて、s3をやりましょう。ここまで長かった。

jpgとjpegの違いは何か?

.jpgと.jpegは同じなのか? 二つとも同じJPEGに見えるが、正確には違うようだ。

MS-DOSではファイルの拡張子が3文字までという制約があった
そういえば、.jpegより.jpgの方が良く見ますね。
しかし、現在のosでは4文字も利用できるため、jpegも対応している。

jpgの略は、Joint Photographic Experts Groupで、4文字の拡張子もOKになったので、jpegが追加された?たったそれだけの理由?

Acrobatにてファイルから直接PDF変換を行える形式: .jpg
PDF以外に保存が行える形式: .jpg/.jpeg

.jpgの方がより多くの機能に対応しているようです。

うーん、ITの世界も極めて天才的な設計がある一方で、こういうイマイチよくわからない経緯もあるんですな。

phpのstrtolowerとは?

strtolower — 文字列を小文字にする

読んで字の如く、という感じですね。
サンプル

echo strtolower("Jpeg");

jpeg

想定通りです。裏側のアルゴリズムを想像すると、ワクワクしますね。
jsやjava、pythonなどでもあるようです。

phpのstrrposで日本語を扱う時

strrpos: 文字列の中に、ある部分の文字列が最後に現れる場所を探す
int strrpos(string $haystack, string $needle)

echo strrpos("あいうえお", "う");

6?
あれ?どういうことだ?

echo strrpos("phpengineer", "h");

1

あれ、半角英数字だと上手くいく。日本語だと駄目なのか?

echo strrpos("日本語で試します", "で");

9

あ、わかった、これはバイト数でカウントしてるんだな。
日本語は一文字3バイトだから、012, 345, 678, 9
で、9ということだろう。

試しに4バイトの漢字を入れてみましょう。
「𡈽」を使ってみます。
参考: UTF-8で4バイトになる文字 https://www.softel.co.jp/blogs/tech/archives/596

echo strrpos("𡈽は4バイトです", "は");

4
あ、やっぱりそうですね。
なるほどー

.gitignoreとは

.gitignoreとは、リポジトリで、意図的に追跡対象から外したいファイルを設定するためのファイル。

例として、.gitignoreの中身を見てみましょう。
.envはもちろんの事、/node_modules、homestead.json|yml、/vendorなども含まれていますね。

/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
/.idea
/.vscode
/.vagrant
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
.env
.phpunit.result.cache

git rm –cachedで追跡対象から外して、そのファイルを.gitignoreに加えればよいでしょう。

composerでaws/aws-sdk-phpインストール時にエラー

aws-sdk-phpを入れようとします。

composer.json

"require": {
    "aws/aws-sdk-php": "3.*",
}
[vagrant@localhost app]$ php composer.phar install aws/aws-sdk-php


  [Seld\JsonLint\ParsingException]
  "./composer.json" does not contain valid JSON
  Parse error on line 1:
    "aws/aws-sd
  --------^
  Expected one of: 'EOF', '}', ',', ']'

あれ? JSONが違う

{
	"require": {
    "aws/aws-sdk-php": "3.*"
	}
}

再度インストールします。上手くいきそうです。

[vagrant@localhost app]$ php composer.phar install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 7 installs, 0 updates, 0 removals
– Installing mtdowling/jmespath.php (2.4.0): Loading from cache
– Installing ralouphie/getallheaders (2.0.5): Downloading (100%)
– Installing psr/http-message (1.0.1): Loading from cache
– Installing guzzlehttp/psr7 (1.5.2): Downloading (100%)
– Installing guzzlehttp/promises (v1.3.1): Loading from cache
– Installing guzzlehttp/guzzle (6.3.3): Loading from cache
– Installing aws/aws-sdk-php (3.82.6): Downloading (100%)
guzzlehttp/guzzle suggests installing psr/log (Required for using the Log middleware)
aws/aws-sdk-php suggests installing doctrine/cache (To use the DoctrineCacheAdapter)
aws/aws-sdk-php suggests installing aws/aws-php-sns-message-validator (To validate incoming SNS notifications)
Writing lock file
Generating autoload files

S3にアップロードしてmysqlに登録:S3 / IAM編

まず、awsコンソールにログインし、S3でバケットを作成します。適当に[zeus-image]としておきましょう。リージョンはアジアパシフィック東京でいいでしょう。

続いてプロパティ
バージョニング、アクセスログの記録、タグ、オブジェクトレベルのログ記録、デフォルト暗号化、cloudWatchリクエストメトリクス、いずれも特に設定はしません。

続いてアクセス権
デフォルトではチェックボックスに全てチェックが入っています。


このバケットのパブリックアクセスコントロールリスト (ACL) を管理する
– 新規のパブリック ACL と、パブリックオブジェクトのアップロードをブロックする (推奨)
– パブリック ACL を通じて付与されたパブリックアクセスを削除する (推奨)

このバケットのパブリックバケットポリシーを管理する
– 新規のパブリックバケットポリシーをブロックする (推奨)
– バケットにパブリックポリシーがある場合、パブリックアクセスとクロスアカウントアクセスをブロックする (推奨)


このまま作成します。

IAMでユーザ追加
ユーザを追加していきます。

アクセスの種類で「プログラムによるアクセス」にチェックを入れます。

アクセスキー IDとシークレットアクセスキーを保存します。

続いて、対象ユーザからインラインポリシーの追加を押下します。

s3の指定bucketへのアクセス付与をします。

うおー、なんかやる気がでねーぞ。
続いてcomposerを入れていきます。

[vagrant@localhost app]$ curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading…

Composer (version 1.8.0) successfully installed to: /home/vagrant/local/app/composer.phar
Use it: php composer.phar

[vagrant@localhost app]$ php composer.phar install aws/aws-sdk-php
Invalid argument aws/aws-sdk-php. Use “composer require aws/aws-sdk-php” instead to add packages to your composer.json.

あれ??

S3にアップロードしてmysqlに登録

やりたいこと
– Laravelから画像をS3にアップロードしてmysqlにパスを登録

-> その為には?
– ブレークダウンして考える
– まず、s3に画像をアップロード
– その後、ユーザID、s3のバケットのパス、ファイル名、ファイルサイズ、ステータスをmysqlに登録する
– ユーザIDに紐づいた画像を画像管理の画面で表示させる

アップロードのHTML、JSまではできている。

<form action="#" method="POST" enctype="multipart/form-data">
        <div id="drag-drop-area">
         <div class="drag-drop-inside">
          <p class="drag-drop-info">ここにファイルをアップロード</p>
          <p>または</p>
          <!-- <input type="file" value="ファイルを選択" name="image"> -->
          <p class="drag-drop-buttons"><input id="fileInput" type="file" value="ファイルを選択" name="image"></p>
              <!-- <input type="submit" value="送信"> -->
           </div>
          </div>
            

      <div class="button_wrapper remodal-bg">
         <button type="submit" value="送信" id="square_btn" onClick="location.href='#modal'">登録</button>
      </div>
       </form> 

ログイン機能は後から作ろうかなと悠著に考えていたが、先に作った方が良いのかな。。
まずは、S3へのアップロードからやりましょう。

ヘッダー(header)を最前面に表示するz-index

プルダウン式のheaderを作っていたのですが、
おいおいおい、なんだこれは、ヘッダーよりもstepのボックスの方が全面に表示されているじゃないか。
ピッツバーグ美術館に飾られているモダンアートみたいになってるぞ。

ヘッダーのプルダウンを最前面に表示したいとき。

cssでz-indexを指定する

mozillaを見てみましょう。
Z-index
The z-index CSS property sets the z-order of a positioned element and its descendants or flex items. Overlapping elements with a larger z-index cover those with a smaller one.

z-indexの値が大きい方が全面に表示されます。下記例だとgoldが最前面です。

では実際にやってみましょう。
stepの該当箇所 z-indexの値を0にします。

.step {
  list-style-type: none;
  display:table;
  width:100%;
  height:50px;
  padding: 0;
  margin: 0;
  overflow:hidden;
  z-index: 0;
}

navigationのcss, z-indexを1にします。

#gNav {
	position: absolute;
	margin-top: 40px;
	float: left;
	width: 100%;
	height:45px;
	background-color: #6a5acd;
	z-index: 1;
}

おいおい、沖縄みたいに浮いてるぞ。

stepを全てz-index:0に変えます。

li.is-current{
	z-index:0;
}

上手く表示されるようになりました。