CentOS9にApache httpd → PHP → MariaDBと入れてPHPからMariaDBへのPDO接続のメモ
▼CentOS9にApache httpd → PHP → MariaDBと入れてPHPからMariaDBへのPDO接続のメモ
・CentOSはローカルのVM。ホストともども192.168.1.0/24にお住まい。
・SElinux、Firewalldは有効。
・Apache入れ、Webサーバへのアクセス確認済み。
・そっからPHP入れ、動作確認済み。
・そっからMariaDB入れ、初期設定やDBやらテーブルやらPHP用ユーザやら作成。
・下記PHPでMariaDBに接続できず。「could not find driver」とかって怒られる。
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8';
$user = 'phpnoyuuzaa';
$pass = 'hogehoge';
try{
$db = new PDO($dsn, $user, $pass);
} catch(PDOException $e) {
die('エラー:' . $e->getMessage());
}
echo('ここまできたらDB接続に成功');
・DBへの到達以前に、DB利用のドライバ周辺が何か足りてない? 下図は解決後の画だが、PDOで検索してもsqliteのことしか見当たらず。ここにmysqlなりmariadbなり的な文言があるべきなのかと。

・何やら php-mysqlnd なるものを入れろとの情報。やってみる。
> sudo yum install php-mysqlnd.x86_64
パッケージのダウンロード:
php-mysqlnd-8.0.27-1.el9.x86_64.rpm 351 kB/s | 152 kB 00:00
--------------------------------------------------------------------------------
合計 98 kB/s | 152 kB 00:01
トランザクションの確認を実行中
トランザクションの確認に成功しました。
トランザクションのテストを実行中
トランザクションのテストに成功しました。
トランザクションを実行中
準備 : 1/1
インストール中 : php-mysqlnd-8.0.27-1.el9.x86_64 1/1
scriptletの実行中: php-mysqlnd-8.0.27-1.el9.x86_64 1/1
検証 : php-mysqlnd-8.0.27-1.el9.x86_64 1/1
インストール済み:
php-mysqlnd-8.0.27-1.el9.x86_64
完了しました!
・いちおうPHP再起動しておく。
> sudo systemctl restart php-fpm.service
・行けた。
> _人人人人人人人人人人人人人人人_
> > ここまできたらDB接続に成功 <
>  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄
”ITやりたい” とか "プログラミングやりたい" 的なフワッとした向きに、とりあえずこのへんググってみて興味や適性を探ってみれば?ていうワード集
・基本情報
→ネタにされがちだが、何だかんだ。より簡単な「ITパスポート」からでも。取得(合格)目指して勉強してます、ってだけでそれなりに伝わるんではなかろうか。
・Web(系)
→よく出てくる。大づかみな「Web(系)」という表現・呼称は、開発(≒プログラミング)的なやつと制作(≒デザイン)的なやつに大別されるので、それぞれの違いをそれとなくつかんで、自分のやりたいことと照らし合わせておくとよいかも。
・職業訓練
→条件次第(厳しくはない)で給付受けつつ勉強できるチャンス。
→地域で当たり外れあるかもしれない。そこそこの地方都市クラス所在で半年くらい(以上)のコースだと、まともそうに見える。
→訓練のための遠隔地引っ越しで補助金出る制度などもあり。
→予習復習自学の努力が不可欠で、かつ受講生のレベルはピンキリ。いかにダメな人らに巻き込まれないようにしつつ、モチベーションを保つかが重要。可処分時間は全部学習に突っ込む覚悟で。
→現在就業中でこれから離職~訓練という流れを考えるなら、失業給付の条件や離職タイミング(訓練申し込みタイミング)など、事前のリサーチ入念に。
・2進とIPアドレス
→初学者でここで死ぬケース多い気がするので、適正見極めも兼ねて味見してみるといいかもしれない。「基本情報 2進 IPアドレス」で検索。
・オブジェクト指向プログラミング
→C言語を除き、初学者に訴求してくるプログラミング言語はほぼ例外なくオブジェクト指向を採用しているはず。なので、どんなもんか調べておくといいかも。
・情報商材、プログラミングスクール、等
→警戒しつつが前提。良質なものはごく限られるので、最初は「近づいちゃダメ」と覚えておく。最初は無料のWeb情報や廉価の書籍で十分。
・〇〇はオワコン、△△歳では厳しい、等
→この手の言説は最初のうちは相手にしないほうがよいと思う。それが真実か妥当か以前に、自分から心折って終わりに向かうこともないでしょ、と。
--
気が向いたらなんか追記したいものです
Ubuntu18のSambaにWindows10からアクセスできなくてハマった
Android N(7)からのhttp(s)接続のこと
なんか変わったぽいので、情報をつまみ食いしてみる。
ネットワーク セキュリティ構成 | Android Developers
こちらとかも。
なんでも、Android7から、ネットワークセキュリティ構成機能(network-security-config)てのが追加されたぽい。
証明書まわりとかで、セキュリティの向上を図っている感じかな。
いろいろあるだろうが、ここでは
・HTTPでの接続は原則、怒られるようになり、回避するには仕込みが必要。
てところを確認してみたい。
(前略。適当にonCreateなり何なり好きなとこに)
(UIスレッドで通信処理すると怒られるので、適当やっつけThreadで書いている。
ほんとはしかるべき非同期処理の記述を選択すべきだろう。)
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection con = null;
URL url = null;
//これは特に問題なく接続。(ステータスコード200返却)
String urlSt = "https://www.yahoo.co.jp";
//こっち(http)は、network-security-configの仕込み必要となる。
//String urlSt = "http://www.yahoo.co.jp";
//※なお接続成功するとステータスコード301返却される。
// 301なのはyahoo側でhttp→httpsにリダイレクトしてるからだろうから、
// 200が返らないのは当然で、また当記事の本質とは関係ないので気にしない。
try {
// URLの作成
url = new URL(urlSt);
// 接続用HttpURLConnectionオブジェクト作成
con = (HttpURLConnection)url.openConnection();
// リクエストメソッドの設定
con.setRequestMethod("GET");
// リダイレクトを自動で許可しない設定
con.setInstanceFollowRedirects(false);
// URL接続からデータを読み取る場合はtrue
con.setDoInput(true);
// URL接続にデータを書き込む場合はtrue
con.setDoOutput(true);
// 接続
con.connect();
// 本文の取得
InputStream in = con.getInputStream();
byte bodyByte[] = new byte[1024];
in.read(bodyByte);
in.close();
System.out.println(con.getResponseCode());
System.out.println(bodyByte);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
インターネット接続なので。マニフェストにはいつもの。
<uses-permission android:name="android.permission.INTERNET"/>
ヤフーに接続(GET)してるだけ。
URLがhttps~ならここまでで十分で、今まで通りの感覚。
さて、httpの場合、network-security-configという機構の仕込みが必要になった模様。
マニフェストには
<application
(省略)
android:networkSecurityConfig="@xml/network_security_config"
>と書いてやり、そのxmlを用意(~res/xml/network_security_config.xml)
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<!-- ここに書いたドメインには、httpで接続しても怒られなくなる、みたいな感じぽい。 -->
<domain includeSubdomains="true">yahoo.co.jp</domain>
</domain-config>
</network-security-config>http接続だと、上記をちゃんとしてないと、
NetworkSecurityConfig: No Network Security Config specified, using platform default
とか
java.io.IOException: Cleartext HTTP traffic to www.yahoo.co.jp not permitted
とか
怒られてしまうようだ。
まあ今日びはhttpsでつなぎなさいよ、てことか。みんな常時SSLとか言ってるしなあ。
証明書の管理とかめんどくさいイメージ(個人の感想です)。
まあ開発環境とかでhttp使うなら役立つかも、てとこかなあ。
脱線するけれど、開発環境といえば、https~で立てるときにオレオレ証明書だとナニな感じなので
無理やり信用しちゃう(エラーを無視する)、みたいなことをやった記憶。
こちらとか参考になるかも。
ishiitakeru-programing-memo.blogspot.com
うっかりこういう設定のままリリースしないように気をつけなきゃ、ですね。
データベースのメモ
ちょっとMySQLをいじりながら、覚えたことを書きなぐる。
表とテーブルはだいたいおんなじ意味で。
▼データベース
データの管理に特化したシステムやアプリ。利用する側(プログラム等)はSQLなど決まった手続きで読み書きし、
管理はデータベース側がおこなう。
RDBという、リレーショナル(関係型)なやつが有名。相互に関係するテーブル(≒表)が複数あるみたいなイメージ。
使う側はSQLで読み書きする。利用する側とRDB側との細かいマッチング差異を吸収するためにAPIが提供されたりしてる。
ODBCとかJDBCとか。
ディレクトリサービスというツリー構造のものもある。LDAPとか。有名どころではActiveDirectoryもLDAP。ほか、OpenLDAPやら。
なんかLDAPしか分かんない。LDAPは狭義にプロトコルのことで、RDBに対するSQLみたいなもんだけど、そこから広がって
サービス・サーバ側のこともLDAPて言ってるぽい。
機能としては、データの更新よりも検索性に重点が置かれてる感じ?
NoSQLてのが、ビッグデータの隆興に前後して、出てきたみたい。DBといえばRDB(SQL)みたいな風潮に、
一石を投じる的な意味も、暗に含むのかもしれない。(このへんはNoSQLとか Not only SQLとかで調べると読み物がいろいろ)
ともあれ、ビッグデータを扱うにはRDBが不向き、みたいな背景から生まれたっぽく、
利用するための手続きとしてはSQLのような汎用性はないものの、ビッグデータ向けのパフォーマンスなどに優れる仕組みで、
なんかナウい感じだそうだ。
▼RDB
いちばんなじみがあるやつ。テーブルが関係しあうアレ。
テーブルの正規化が重要だそうで、資格試験とかにもそのへんが頻出。
正規化は第五正規形まであるが、上位の試験やDB最前線的な現場でない限り、
第三正規形までで概ね用が足りるみたいだ。
・非正規形
繰り返しがあるorありうるような作り。主キーとかも特に無かったりとか。
「これ表にしようか」って思うようなモノや、その土台の帳票とか、っていうイメージ。
主キー:その行を一意に特定できるデータ列みたいなもん。モノによるけど、IDとか社員番号とか。
・第一正規形
非正規形から繰り返しを排除して主キーを設定したテーブル。
なおこの段階で第二正規形や第三正規形にすでに到達してることもありうる。
・第二正規形
第一~から部分従属を排除したもの。
複合キーな主キーについて、その一部だけで定まるような列がない(存在しないor別テーブルに切り出した形)。
・第三正規形
第二~から推移従属を排除したもの。
列P,Q(,R)があったとして、
・PならばQが一意に定まる。
・QならばRが一意に定まる。
・RならばPは一意に定まらない。
ような部分がない(存在しないor別テーブルに切り出した形)。
社員番号|名前|部署ID|部署名|部署代表者名 とかを
社員番号|名前|部署ID と 部署ID|部署名|部署代表者名 とに分ける、みたいな。
・テーブル間の関係はキー(外部キー)で紐づくので、テーブルの切り出し時は適切なキーを設定する。
・モデル図で語るならER図を使う。1対多とか、0以上とか、1以上とか、0or1とか、そんなんも表現できる。
・インデックス付けると検索のパフォーマンスup、更新のパフォーマンスdown。
トレードオフなので、インデックスの検討が必要なら、考えて設計しないと、な感じ。
マスタデータテーブルは更新頻度低、参照されること多し、な性質なので、インデックスが向くかも、
トランジションデータテーブルは更新頻度高、参照されること少なし、な性質なので、インデックス不向きかも、
・・・みたいに考えるのかな?
▼つくり
トップダウン型:イチからデータベースを設計していく。手持ち資源が非正規形だったり。
ボトムアップ型:すでに点在するデータ(テーブル類)をうまいこと集めてつなげてデータベースに仕立て上げていく。
AndroidのViewやらonDrawやらCanvasやらを少し触ってみる
何の気なしに開いた解説書で、自前のViewを使って描画、みたいなのに目がとまった。
絵とかそのへんの処理は経験少なくて苦手なので、少し動かしてみて理解を進めるぞ、と。
今回作るもののイメージとしては、
レイアウト->View->Viewに乗っけたグラフィック
の順で背面から詰まれてる感じかしら。

▼呼び出すほう
1: レイアウトを用意。
2: ビットマップを用意。適当な画像とかで。
3: Viewのサブクラス(後述)のインスタンスを用意。コンストラクタにはビットマップを渡す。
4: レイアウトのaddView()に3のインスタンス渡すことで、レイアウトに貼り付けてやる。
みたいな感じ。
3のインスタンス.postInvalidate()
とかやるとそのたび、Viewインスタンスの描画処理部分であるonDrawを呼べる。
onDrawはViewの描画処理実体なので、一定間隔でpostInvalidate()を呼ぶことで、
アニメーション(パラパラ漫画)を実現できる。
UI(メイン)スレッドから呼ぶときはinvalidate()でいけるが、
アニメーション処理は別スレッドにするのが良い作法らしく、そのばあいpostInvalidateでないとダメだそう。
▼呼ばれるほう(View)
・Viewのサブクラスとして自作。
・中身では、描画のための諸準備とかを仕込み、onDrawメソッドをオーバーライドして描画処理を書いてやる。
・引数でもらったビットマップを、onDrawの中で、座標をちょっと変えたり少し回転して描画するような処理を書いてやれば、
呼び出し側でpostInvalidate(つまりonDraw)を繰り返し呼ぶことで、アニメーションが表現できる。
動かしてみた。おおー、すごい。
ビットマップに、ポプ子ギュルギュル回転画像を用いたら、かわいくて楽しかったです。
回っとるやろがい!

MainActivity
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.widget.RelativeLayout;
import java.util.Random;
/**
* Canvasを使うプログラム(Viewのサブクラスを使う方法)
* 画面上を、ビットマップが、回転しながら移動するアプリ。
*/
public class MainActivity extends Activity {
static final int SAIBYOUGA_KANKAKU_MS = 20; //viewの再描画の間隔(ms)。小さいほどアニメーションが滑らかに。
static final int SAIBYOUGA_COUNT = 5000; //再描画回数の指定。再描画用スレッド内の処理でインクリメントがこれに達すると終了。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//ベースとなるレイアウトを得ておく。
RelativeLayout relativeLayout = findViewById(R.id.activity_main);
//ビットマップ(=回転する絵)を得ておく。
final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ppk); //drawableに突っ込んでおいた画像を使用。
//viewのサブクラスを得ておく。レイアウトに乗っかる、絵コンテンツの総体、とでも捉えたらよいのかな。
final MyView myView = new MyView(this,bitmap);
//ベースのレイアウトにviewをaddする。乗っける、的な?
relativeLayout.addView(myView);
//基本は、ViewのonDraw内(描画処理の実体)を1回呼んでおしまいなので、
//1枚絵ならば、ここまでで完成。
//アニメの理屈は、view丸ごとの再描画を、任意の間隔で繰り返す感じ。
//んで今回は、再描画ごとにカウンタをインクリメントして、指定回数到達で停止、のような実装。
//再描画ごとの移動や回転、つまり動きの表現は、viewのほうに仕込んであり、それが繰り返されることでアニメーションを表現。
//Viewの描画処理(onDraw)を繰り返し呼ぶのはスレッド作っておこなう。UI(メイン)スレッドではやらない行為、なのだそうだ。
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<SAIBYOUGA_COUNT; i++){
try {
Thread.sleep(SAIBYOUGA_KANKAKU_MS);
} catch (InterruptedException e) {
e.printStackTrace();
}
myView.postInvalidate(); //←コレで結果的にViewのonDrawを呼ぶのだそう。
//類似のinvalidateというメソッドもあるが、別スレッドからの場合はこちらのpost~を使うとのこと。
myView.move(); //再描画後にコレ。次の描画用に、新しい位置座標などを更新してる。
}
}
}).start();
}
/**
* Viewのサブクラスを定義
* 背景と、その上に乗っかった絵(=コンストラクタ引数で渡ってくるビットマップ)。
* 描画処理実体はonDraw内に書かれているcanvas.~ のところ。
* (on)Invalidateで再描画される、つまりインスタンスのonDrawが呼ばれるたび、
* canvas.~で仕込んである回転や移動処理が実行され、結果動いて見える。
*/
private class MyView extends View {
private static final int STEP = 50; //これ増やすと、起動ごとの速度設定(ランダム)のふり幅が大きくなるようだ。
final private Bitmap bitmap;
float currentX;
float currentY;
float dx;
float dy;
int bitmapHeight;
int bitmapWidth;
float rotation;
int canvasWidth = 0;
int canvasHeight = 0;
final private Paint mPainter = new Paint();
/**
* コンストラクタ
*/
public MyView(Context context, Bitmap bitmap){
super(context);
//WindowManagerクラスとDisplayクラスを使って画面のサイズを取得する
Display display = getWindowManager().getDefaultDisplay();
Point point = new Point(0,0);
display.getSize(point); //ここの処理で、引数(Point outSize)に渡した変数に対し、ディスプレイサイズのピクセルが代入される。
int displayWidth = point.x; //ディスプレイ幅を取得。
int displayHeight = point.y; //同、高さを取得。
//引数に取ったビットマップ(今回は乗っかってる絵)とその幅&高さを得る。
this.bitmap = bitmap;
bitmapHeight = bitmap.getHeight();
bitmapWidth = bitmap.getWidth();
//開始位置を指定。画面中央は、ディスプレイ幅の1/2と高さの1/2で得ている。
float x0 = (float)(displayWidth/2);
float y0 = (float)(displayHeight/2);
//x方向、y方向の、描画ごとの移動量。変えると、アニメーションの移動速度が変化する感じか。
//ここでは起動のたび(MyViewインスタンス生成のたび?)Randomで速度が変わっている。
Random r = new Random();
dx = (float)(2.0*r.nextFloat()-1.0) * STEP;
dy = (float)(2.0*r.nextFloat()-1.0) * STEP;
//これはよくわからない。x0,y0でも動くぽいが。
currentX = x0 - bitmapWidth/2;
currentY = y0 - bitmapHeight/2;
//アンチエイリアスの設定。View内の描画物に対して機能するのかな?よくわかんない。
mPainter.setAntiAlias(true);
}
/**
* onDrawは、Viewのインスタンスが作られた(レイアウトにaddViewされた?)ときと、
* そのインスタンスで(on)invalidateが呼ばれたときに、実行されるそうだ。
* View上に描きたい内容は、ここで渡されるCanvas canvasを使って描く感じか。
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.DKGRAY); //背景色を設定。
canvasWidth = canvas.getWidth();
canvasHeight = canvas.getHeight();
canvas.rotate(rotation, currentX + bitmapWidth/2,currentY + bitmapHeight/2); //回転角度は第一引数、後ろ2つの引数で回転の中心座標を決め。
//なお後ろ2つを0,0とかにするとわかるが、rotateは、Canvasごと(viewごと)回転させる。
//ここでは、回転の軸が常に、乗っかっているビットマップ絵の中心になるように仕込んでるので、
//結果的に見た目としては、絵だけが回転しているように見える。
float rotationDegree = 30; //再描画ごとに回転する角度
rotation += rotationDegree;
//ビットマップの描画
canvas.drawBitmap(bitmap,currentX,currentY,mPainter);
}
/**
* 移動後の位置を計算
* ディスプレイ領域から外に出ないように制御してる感じかな
*/
protected void move(){
if(currentX + dx < 0){
dx = -dx;
}
if(currentY + dy < 0){
dy = -dy;
}
if(canvasWidth < currentX + dx + bitmapWidth){
dx = -dx;
}
if(canvasHeight < currentY + dy + bitmapHeight){
dy = -dy;
}
currentX += dx;
currentY += dy;
}
}
}activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="@+id/activity_main"
>
<!-- ここは特に何も書かず。 -->
</RelativeLayout>