DBドライバーについては一旦おいておくとして……
質問への追記・修正の欄にも書きましたが、変数のスコープについての理解が足りていないように思います。
大雑把にいうと、「変数を宣言した場所」と「変数にアクセスしようとする場所」の組み合わせによって、実際に変数へのアクセスが期待通りに動くかどうかは違いますよ(=期待通りに動かそうとしたら適切に処理をしてあげる必要がありますよ)という話です。
php
1 // インデントがおかしいところだけ直しています
2 function error_message($mysqli) {
3 try {
4 if ( $mysqli->connect_errno ) {
5 throw new Exception(); // ← [1]
6 }
7 } catch(Exception $e) {
8 // ↓ [2]
9 $error_message[] = '書き込みに失敗しました / エラー番号 '.$mysqli->connect_errno.' : '.$mysqli->connect_error;
10 }
11 }
まず、このコードの [1] は、Exceptionになったときの動作を確認するためにとりあえず入れているだけで最終的には不要なコードですかね?であればとりあえず無視しようと思いますが、人に見せるのですからコメントを入れるなりしてください。
問題は [2] ですが、ここで唐突に $error_message
という変数が登場していますが、先のリンクのとおり、 functionの外で宣言された $error_message
とは無関係な新しい $error_message
を参照しようとしています。
もっと短いコードで試すとわかりやすいと思うのですが、以下のコードの最後の print_r()
は、「要素が0個の配列」を表示します。
これは、4行目でアクセスしている $arr
は2行目で宣言された $arr
とは別物だからです。
php
1<?php // 1
2$arr = []; // 2
3function foo() { // 3
4 $arr[] = 'bar'; // 4
5} // 5
6foo(); // 6
7print_r($arr); // 7
関数の外で宣言した変数に、関数の中からアクセスする最も簡単な方法は、 global
キーワードを使うことです。
が、これはおすすめしません。これはつまり、「関数の外で宣言した変数に、関数の中からアクセスすることができない」という基本設計があって、それを回避する小技がある、という話なわけですが、設計には理由があります。こういう設計であったほうが使いやすかったり安全だったりするのです。
小技を使わなくてもうまく動作させる手段はあるので、そちらへと舵をきってください。たとえばこんなんとか。
php
1<?php
2$arr = [];
3
4function add_message_to_array($arr) {
5 $arr[] = 'foo';
6 return $arr;
7}
8function new_message() {
9 return 'bar';
10}
11
12// アクセスしてほしい変数を渡してあげる
13add_message_to_array($arr);
14
15// 変数にアクセスするのは同じスコープの場所 (ここではfunctionたちの外) でやるようにして、
16// その中身に入れたいものだけ返してもらうようにする
17$arr[] = new_message();
18
19print_r($arr);
私はクラスにしてしまったほうがいいと思いますが、習熟度的には次のステップかもしれないですね。