ZAPAnet総合情報局 > ZAPAブログ2.0 >

CSSで長方形の画像を丸く表示する方法

radius_03

画像をCSSでまん丸に表示する方法について調べたときのメモです。

CSS3にある「border-radius」というプロパティを使うと、角を丸めることができます。画像も同様にして丸めれば、真ん丸の画像が表示できると思いました。以下のようなHTMLとCSSを書いて、実際に試してました。
<div class="none">
  <img src="https://zapanet.info/zapanet_fav.png">
</div>
<div class="radiustest1">
  <img src="https://zapanet.info/zapanet_fav.png">
</div>
.none{
  
}
.radiustest1 img{
  border-radius: 50%; 
  width: 150px;
}
「.radiustest1 img」で「border-radius: 50%;」を設定して、画像を丸くします。「width: 150px;」は横幅を指定のピクセルに縮小して表示します。

表示はこのようになりました。
radius_01
バッチリです。正方形の画像が真ん丸に表示されました。

続いて、長方形の画像もCSSで円形にしてみます。
2020年06月29日 プログラミングTIPS

CentOS 8 に Amazon AWS Cloud9 をインストール

さくらのVPSの CentOS 8 サーバーに、 Amazon AWS Cloud9 をインストールしたときのメモです。


開発に利用するマシンが複数台ある場合、一般的にはマシンごとに開発環境の設定値が異なり、それだけでストレスがたまります。ローカルファイルやオンラインファイルの同期も必要です。今の時代、開発環境もすべてクラウド上で構築できるなら、そちらの方が楽です。

Cloud9は、WebからアクセスできるオンラインIDE(統合開発環境)です。Webブラウザさえあれば、どのマシンからでもコードを記述、実行、デバッグできます。エディタの操作については、コード補完、コードヒント候補、エラー表示、ドラッグ&ドロップ操作、Ctrl+Sで保存など、まるでPCネイティブのアプリケーションを操作しているような感覚でブラウザから開発できます。ターミナル、プレビュー表示、テーマ、キーボードショートカットなどの機能も備えています。クラウドベースのため、オフィス、自宅、移動中、布団の中…どこでも同じ環境でプログラミングすることができます。Cloud9の初期設定さえ済ませれば、「プログラミングに必要なものはブラウザだけ」という夢の環境を構築できることになります。開発マシンの種類や性能は問われません。

また、Cloud9 IDEは、C 、 C ++ 、PHP、Ruby、Perl、Python 、Node.jsを伴うJavaScript 、Goなどの複数のプログラミング言語をサポートしています。Cloud9自体は、JavaScriptでほぼ完全に記述され、バックエンドでNode.jsが使われています。Cloud9は2016年7月にAmazonが買収しました。AWSユーザーには有名な開発環境となっています。

Cloud9は、実はAWS以外のサーバーでも利用できます。ということで、さくらのVPSの CentOS 8.1 サーバーに、 Amazon AWS Cloud9 をインストールしてみたというわけです。Amazon公式で解説されている「AWS Cloud9 インストーラ」を使えば簡単にインストールできそうですが、実際には難しかったので、手順を追ってログとして残しておきます。

Node.jsのインストール確認

まずは、Cloud9のバックエンドとして動いているNode.jsのインストールから。ターミナルから「node -v」と打って、サーバーにnodejsがインストール済みか確認。
node -v

Node.jsのインストール

バージョン確認で何か表示が出てきたらインストール済み。インストールされていなかったら、以下の方法でCentOS8.1にnodejsをインストールできる。
dnf module list nodejs
dnf module -y install nodejs:12
(あるいは、dnf module -y install nodejs:12/defaultなど)
インストールしたnodeとnpmのバージョン確認。
node -v
→v12.16.1(バージョン確認)

npm --version
→6.13.4(バージョン確認)

Node.jsのアンインストール

上記の方法でnodejsはインストールできるが、npmのパッケージが古いとかいろいろ問題が出てきて、今後のバージョン管理にも不具合が出てきそうだったので、上記方法でのnodejs管理方法はやめ。

いきなりnodejsをアンインストール。
dnf remove nodejs

nodebrewのインストール

nodejsを直接インストールする代わりに、nodebrewをインストール。
dnf -y groupinstall 'Development tools'
curl -L git.io/nodebrew | perl - setup

以下のように表示されれば、nodebrewのインストールに成功。
Fetching nodebrew...
Installed nodebrew in $HOME/.nodebrew

========================================
Export a path to nodebrew:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================

環境変数を追加。
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

パスが通っているか確認。「nodebrew 1.0.1」等と表示されればOK。
nodebrew help

Node.js公式ページを見て、node.js最新推奨版(LTS)をバイナリでインストールする(バイナリだと、インストールが速い!)。「Installed successfully」と表示されればOK。
nodebrew install-binary v12.18.1

使用するnodejsのバージョンを指定。以下のuseコマンドを打って、「use v12.18.1」等と表示されればOK。インストールするnode.jsと使用するバージョンの切り替えが簡単なので、nodebrewは圧倒的に楽。
nodebrew use v12.18.1

続いて、npmのバージョンを確認。「6.14.5」等と表示されればOK。
npm -v
これでNode.jsとnpmの利用準備は完了。

Python 2.7 をインストール。

Cloud9にはPython3系ではなく、Python2.7を使う。Python 2.7 をインストール。
dnf module -y install python27

gitのインストール確認

次はgitのインストール(すでにインストールされていれば必要なし)。
dnf -y install git

ここが超難関のglibc-staticのインストール。
dnf -y install glibc-static

上記コマンドを打っても、以下のエラーが返ってきてインストールできない。
No match for argument: glibc-static
Error: Unable to find a match: glibc-static

実は、glibc-staticは、Red Hat系OSからは削除されている。インストールは推奨されていない。

それでも無理やりglibc-staticをインストールするなら、以下のコマンドで(自己責任で)。
dnf --enablerepo=PowerTools install glibc-static

GitHubとの連携設定

GitHubと連携するため、SSH認証用の鍵を作る。事前にGitHubのアカウントが必要。アカウントがない場合は、アカウントを作っておく。
ssh-keygen -t rsa -b 4096 -C "GitHubに登録済みのメールアドレス"
Enter file in which to save the key :鍵の置き場所

chmod 600 作った鍵ファイル
eval "$(ssh-agent)"
ssh-add 作った鍵ファイル
ssh-add -l

作った公開鍵を開く。中身の文字列を全てコピーする。
view 作った鍵ファイル(.pubの方)

GitHubの方で、「SSH and GPG keys」を選択し、コピーした文字列をGitHubに登録


コンフィグファイルの作成。
vi 鍵がおいてあるディレクトリ/.ssh/config

configファイルに以下のように記述して保存。
Host github.com
 HostName      github.com
 IdentityFile  作った鍵ファイル
 User          git

動作確認。下記コマンドで、「Hi ユーザー名! You've successfully authenticated,」と表示されればOK。
ssh -T git@github.com

Cloud9のインストール

ようやく、Cloud9のインストールに取りかかる。まずは、Cloud9の作業スペースとインストール場所の作成(場所は各自自由)。
mkdir /opt/workspace
chmod 777 /opt/workspace
cd /usr/local/src
chmod 777 /usr/local/src

インストール。
git clone git://github.com/c9/core.git c9sdk
cd c9sdk
scripts/install-sdk.sh

成功すれば、以下のように表示される(もしうまく行かなかった場合は、エラー内容をよく読んで修正し、install-sdk.shをやり直す)。
Success!
run 'node server.js -p 8080 -a :' to launch Cloud9

ポート、ユーザー名、パスワード、IPアドレスを指定するには、以下のようにする。
node ./server.js -p 8080 -a user:password -w /opt/workspace/ --listen サーバのIPアドレス

firewalldのポートを開けたいときは、以下のようなコマンドを使って解放する。さくらのVPSなど、パケットフィルタでポートが塞がれている場合はそちらも確認する。
firewall-cmd --permanent --add-port 8080/tcp
firewall-cmd --reload
firewall-cmd --list-port
systemctl reload firewalld.service

ポートが開放できたら、node ./server.js コマンドを打ったときに出てきたアドレスにアクセスする(8080番ポートを指定したのなら、http://IPアドレス:8080など)。このような画面が出てきたら成功。エラーが表示されたら、それをがんばって直す。



hello.phpを作り、Hello,World!を表示するPHPファイル作ってみる(適当に打ったらタイプミスした)。


hello.phpを保存してみる。Windows PCと同じように、Ctrl+Sで保存できる。ブラウザ上で保存すると、サーバーのターミナル側には、以下のようにリアルタイムで処理が表示される。
User saving /hello.php
Successfully saved /hello.php


作成したPHPファイルを外部のWebブラウザから直接表示できるようにする。nginxの場合、nginx.confを編集。
vi /etc/nginx/nginx.conf

Cloud9で8080ポートを使っているので、Nginxでも8080を使おうとすると…(下記設定は各自の環境に合わせて)
    server {
        listen       8080;
        listen       [::]:8080;
        server_name  _;
        root         /opt/workspace;
        include /etc/nginx/default.d/*.conf;

        location / {
        }
    }

nginxを再読込し…
systemctl reload nginx.service

もう一度Cloud9を立ち上げようとすると、怒られる。
Error: listen EADDRINUSE: address already in use IPアドレス:8080
    at Server.setupListenHandle [as _listen2] (net.js:1313:16)
    at listenInCluster (net.js:1361:12)
    at doListen (net.js:1498:7)
    at processTicksAndRejections (internal/process/task_queues.js:85:21)
Emitted 'error' event on Server instance at:
    at emitErrorNT (net.js:1340:8)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  code: 'EADDRINUSE',
  errno: 'EADDRINUSE',
  syscall: 'listen',
  address: 'IPアドレス',
  port: 8080
}

8080はCloud9で使うので、nginxでは使うなということ。Webからページを表示させたいときは、他のポートを使用する。例えば、httpの80やhttpsの443(SSL)。テスト用に自分だけ表示できれば良いのなら、8081ポートとかを適当に使う(公開せず、自分専用の開発環境の表示確認なら、Basic認証を設定しておくとなお良い)。
    server {
        listen       8081;
        listen       [::]:8081;
        server_name  _;
        root         /opt/workspace;
        include /etc/nginx/default.d/*.conf;

        location / {
        }
    }

この場合も、ポート開放を忘れないようにしなくてはいけない。firewalldを設定し、nginxを再起動し、Cloud9の起ち上げまで、一連の動作。
2020年06月28日 プログラミングTIPS

CentOS8にhtopをインストール

サーバーのCPU使用率やメモリ消費量を確認する上でお世話になっていた「top」コマンド。「top」コマンドはそのままでは複数コアのCPU使用率が見えないので、今までは数字の「1」を押してコアごとの使用率を見たりしていました。

そんなときに、齊藤貴義@サイバーメガネさんのツイートを見かけました。

「htop」コマンド…そういうのもあるのか、ということでマイナビニュースをチェック。
取り上げられているコマンドは多くのLinuxディストリビューションで利用できるほか、macOSやFreeBSDといった他のオペレーティングシステムでも使用できる。

早速、CentOS8.1のサーバー上で「htop」コマンドを打ち込んでみると…
-bash: htop: command not found
そんなコマンドは使えませんでした。

ということで、「htop」をインストール(CentOS7までの場合は、dnfではなくyumでインストールします)。
dnf install htop


EPELリポジトリに「htop」のパッケージが見つかりました(リポジトリを追加していない場合は、EPELリポジトリを追加する必要があります)。
2020年06月27日 プログラミングTIPS

PHPのセッションファイルの保存場所と設定場所

前記事「PHPでセキュアなクッキーとセッション」からの続きです。

サーバー内でPHPのセッションファイルがどこに保存されているか知りたいとき、ありますよね。サーバー、OS、Webサーバー、PHPを入れ替えたときなどは特に(なかなか変える機会はないですが)。

そんなときは、PHP関数のphpinfo()関数を実行すれば、セッションファイルの格納場所がわかります。以下のようにphpinfo.phpというファイルを作り(ファイル名は適当です)、実行します。
<?php
  phpinfo();
?>
アクセスすると、サーバーのPHP情報一覧が表示されます。その中にsessionセクションがあり、session.save_pathの項目に、セッションファイルのパスが以下のような感じで書かれています。
session.save_path	/var/lib/php/session	/var/lib/php/session


これでPHPのセッションファイルがどこに保存されているかわかりました。

続いて、このセッション保存場所をどこでどのように設定しているのか、サーバーからコマンドを入力して調べてみます。
php -i | grep session.save_path
            
session.save_path => no value => no value
今利用しているサーバーの場合、session.save_pathはno valueでした。「設定されていないのに、設定されている?」と不思議な気持ちになります。詳しくは、php.iniを開いて確認してみます。CentOS8の場合、以下の場所にphp.iniファイルはあります(もしphp.iniの場所がわからない場合は、上記phpinfo.phpを実行して、「Loaded Configuration File」の項目を確認してみて下さい)。
/etc/php.ini
php.iniの中を確認しても、session.save_pathの行はコメントアウトされていて、何も書かれていません。代わりにこんなものがありました。
; RPM note : session directory must be owned by process owner
; for mod_php, see /etc/httpd/conf.d/php.conf
; for php-fpm, see /etc/php-fpm.d/*conf
;session.save_path = "/tmp"
mod_phpで動かしている場合、conf.d/php.confにあるということでした。
2020年06月27日 プログラミングTIPS

PHPでセキュアなクッキーとセッション

サーバーをさくらのVPSに移転後、Google ChromeでPHPページを確認したら、警告が出ていました。
A cookie associated with a cross-site resource…SameSite=None` and `Secure`
安全なWebのために、Googleでは2020年2月のChrome 80から、セキュアなクッキーの利用と接続が推奨されるようになっています。
SameSite 値を宣言していない Cookie は SameSite=Lax の Cookie として扱われます。サードパーティ コンテキストで利用できるのは SameSite=None; Secure が設定されている Cookie のみになり、それも安全な接続が使われている場合に限られます。

session.cookie_samesite を設定

Chromeのデベロッパーツールで警告が出ている以上、警告が出ないように修正する必要があります。幸い、PHP7.3からは、php.iniで簡単に設定できるようになっています。昔のPHPには存在しなかった「session.cookie_samesite」のオプションが追加されています。
session.cookie_samesite
設定値は、Lax、Strict、Noneなどを設定します。例えばNoneにするなら、以下のように書き換えて設定します。
session.cookie_samesite = "None"
最初、「session.cookie_samesite = None」としたら、samesiteの値が空でした。「session.cookie_samesite = None」ではなく、「session.cookie_samesite = "None"」です。文字列での設定です。あまりネットに情報が出回っていませんので、ご注意ください。
2020年06月26日 プログラミングTIPS

PHPのリネーム関数は上書きする

先日の「ブログのデザインとシステムをリニューアルしました」の時に、「iPhone(iOS6以上)対応画像アップロードプログラム」も自分用に改良したことを書きました。スマホから複数枚の画像をアップロードできるように改良し、画像を削除できる機能も付けました。その後、画像ファイルの名前をリネームできる機能も付けました。この「リネーム」の処理が少し危なかったので、メモとして残しておきます。
アップローダー

PHPの関数では、アップロードされたファイルを移動するときは「move_uploaded_file」関数を使います。一方、既存のファイルを移動するときは「rename」関数を使います。move_uploaded_file()とrename()、この統一感のない関数名がPHPの面白いところだななどと思っていたら、ちょっとした罠が。
rename ( string $oldname , string $newname [, resource $context ] ) : bool

oldname を newname にリネームし、必要ならディレクトリを移動しようと試みます。 ファイル名の変更かつ newname が存在する場合、上書きされます。 ディレクトリ名の変更かつ newname が存在する場合、 この関数は警告を発します。
「ファイル名の変更かつ newname が存在する場合、上書きされます」という仕様です。特に警告もなく、いきなり上書きしちゃうんですね。以下のページでも話題になっていました。

自分でファイルのリネーム処理を実装したとき、当初は「自分で名前を変更するわけだから、同じ名前を付けてしまうことはないだろう」などと考えていました。実際に画像ファイルのリネームをやってみたところ、変更後の名前をコピペで貼り付け、そのあと連番を付けようとしていたのに、コピペの段階でリターンキーを押してしまいそうになりました。そのままリターンキーを押していたら、画像を上書きして、元の画像ファイルが上書きされて消失していたというわけです。実際に上書きしてしまったわけではありませんが、このままでは危ないので、確認処理を追加しました。以下のような感じです。
2020年06月25日 プログラミングTIPS

beforeunloadはiOSで効かない

フォームの入力途中に画面遷移しようとした場合に、警告を出すJavaScriptはないかなぁと考えました。誤った操作で、フォームへの入力内容が全て消えてしまうのは悲しすぎますから。jQueryか何かで簡単に実装できるだろうと思って探してみました。
試しに上記サイトの通り実装してみたところ、Windows PCのWebブラウザからは警告が出ました。ところが、iPhoneのWebブラウザSafariからはアラートが出ません。

「あれ、なんでだろう?」と思っていろいろ調べてみました。
2020年06月24日 プログラミングTIPS

Enterキーを押されても実行されないフォームの作り方

formのinput入力欄でEnterキー(リターンキー、実行キー、決定キー)を押されてページ遷移させたくないとき、ありますよね。インクリメンタルサーチを実装したときなどは、わざわざエンターキーを押して画面遷移される必要性がありません。また、ページ内ですべて完結する処理も、POSTして画面遷移される必要がありません。例えば、以下のようなページです。
Enterキーを押しても実行させないフォームの作り方

Submitのボタンを消せば、ページ遷移を防げそうですが、input[type=text]のフォームが一つだけで、そのフォーム内でEnterキーを押されると実行されてしまいます。これを防ぐには、javascriptで別途処理を書いたり、「 onSubmit="return false;"」などとする方法があります。

ただ、最近のブラウザはもっと賢くて、もっと簡単に送信を防ぐことができるようになりました。ダミーフィールドの使用です。
2020年06月23日 プログラミングTIPS

iPhone(iOS)でtextareaやinputのフォーカス時にズームする理由と解決策

ios 16px zoom


iPhoneで入力欄にカーソルを合わせたとき、自動的に画面がズームアップする機能があります。ユーザー側としては、勝手に拡大表示されて面白いなぁと思っていました。ところが、Webページ提供側から見ると、「勝手に拡大するな」と言いたくなるときもあります。このiPhoneでの「勝手に拡大する」「拡大しない」の違いは一体何なのか、調べてみました。

まず、Google Chromeのエミュレータから、スマホ向けのレスポンシブデザインのページを動作確認してみました。Chromeのエミュレータからだと、入力欄にカーソルを合わせても拡大しません。これだと、iPhoneの自動ズーム問題に気付かないことがあります。実機での動作確認は絶対に必要です。「スマホ表示だから拡大する」のではなく、「iOSだから拡大する」というApple側の仕様です。

調べてみたところ原因は、「フォーム入力欄のフォントサイズが16px未満だと、iOS側で勝手にズームする」という仕様になっていました。

原因がわかれば、対処方法は簡単です。一番簡単に解決する方法は、textareaやinputなどのフォントサイズを16px以上にすることです。単純明快です。

例えば、inputのテキストフォームにフォーカスを合わせたときに自動拡大させたくないなら、CSSでこのようにします。
input[type=text]{
  font-size: 16px;
}
2020年06月22日 プログラミングTIPS

www付きのサブドメインをSSLドメインに転送できなかったときのメモ

httpのwwwアクセスをhttpsのwwwなしドメインにリダイレクトすることはできるのに、httpsのwwwアクセスをhttpsのwwwなしドメインにリダイレクトできなかったときのメモです。

あらかじめWebサーバーのNginxで、サブドメインwww付きのアクセスはすべてwwwなしにリダイレクトするように設定していました。例えば、「http://www.zapanet.info/blog/」にアクセスすると、SSL対応の「https://zapanet.info/blog/」に転送できるようにしていました。

ところが、「https://www.zapanet.info/blog」にアクセスしても、「https://zapanet.info/blog/」には転送されなくて失敗しました。httpからhttpsには転送できるのに、httpsからhttpsには転送できませんでした。なんででしょう?

Webサーバー側の設定はできているはずなのに、なぜかエラーが起きて転送されません。「この接続ではプライバシーが保護されません」と表示されてしまいます。常時SSL化はしてあるはずなのに。


なんでかなぁとよく考えたら、取得したSSL証明書がサブドメインに対応していないからでした。「zapanet.info」はSSL化していましたが、「www.zapanet.info」はSSL化していなかったということです。

では、どうするか。

取得したSSL証明書は、「Let's Encrypt - フリーな SSL/TLS 証明書」です。
letsencrypt

Let's Encryptで、サブドメインも含めたSSL証明書に更新すれば良かったというわけです。最初にCentOS8のサーバー上でcertbot-autoコマンドで取得した証明書は以下でした。
certbot-auto certonly --webroot -w ファイルのあるディレクトリ -d zapanet.info
2020年06月21日 プログラミングTIPS