なるの備忘録

エンジニアリングそして営業ができるエンジニアに向けて、日々学んだことをアウトプットしていきます。

初期値が入っている関数に新たに変数を追加するときの注意点(PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function)

実施したいこと

元々用意していた関数では機能が足りなくて、変数を追加したい状況はよくあると思います。
以下の関数に新しい変数$var_eを追加する場合を例に考えます。

元々の関数

function hogehoge($var_a = 1, $var_b, $var_c, $var_d =10){
}

関数を使用するコード

$var_a = 1; 
$var_b = 2;
$var_c = 3;
$test_value = hogehoge($var_a, $var_b, $var_c);

エラーが発生したコード

引数を追加した関数

function hogehoge($var_a = 1, $var_b, $var_c, $var_d =10, $var_e){
}

変数を追加したコード

$var_a = 1; 
$var_b = 2;
$var_c = 3;
$var_c = 4;
$test_value = hogehoge($var_a, $var_b, $var_c, $var_e);

発生したエラー「PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function hogehoge()」

引数が少ない?ちゃんと関数を呼び出す側でも引数は渡しているんだけど…

修正したコード

修正した関数

function hogehoge($var_a = 1, $var_b, $var_c, $var_e, $var_d =10){
}

関数を使用するコード(特に変更なし)

$var_a = 1; 
$var_b = 2;
$var_c = 3;
$test_value = hogehoge($var_a, $var_b, $var_c, $var_e);

関数側の引数の順番を変更することで無事動作しました。

結論

「関数側で引数の初期値を持たせていて、呼び出す側で変数を渡さない」場合、関数側の引数の順番に注意する必要があります。変数を渡さない引数に関しては、関数の最後に設定しましょう。
関数は引数に初期値が入っているかを意識せず、記載順に頭から変数が入っているかを確認していくようです。今回の場合だと、4番目の引数まで値が入っているかを確認した後に5番目の引数が足りないぞ、とエラーを吐くようですね。

配列の内容を折れ線グラフとして表示する(PHP+JavaScript)

配列の内容を折れ線グラフとして表示する(PHP+JavaScript

chart.js を利用したグラフ表示

今回は「chart.js」というライブラリを利用します。
Chart.jsは簡単に使えます。
Chart.jsを使うのに必要なものは2つだけ。
以下の2つをhtml部分に記載。

Chart.jsのインストール
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script>
canvas要素:Chart.jsがHTML5canvas要素内にグラフを記載するため
<canvas id="myChart"></canvas>

基本的なグラフ表示の方法

最小限の折れ線グラフをChart.jsで作るのに必要なものはこれだけ。
htmlのの中のどこかで、上記の2つと次のコードを記述するだけでグラフが表示されます。

<canvas id="myChart"></canvas>
<!-- グラフ用のchart.jsの読み込み -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script>

<script>
    var ctx = document.getElementById('myChart').getContext('2d');
    var myChart = new Chart(ctx, {
        type: 'line',//線の種類
        data: {
            labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],//横軸のラベル
            datasets: [{
                label: あなたの体重,
                lineTension: 0, //グラフの曲がり度合い(デフォルトは0.5)
                fill: false, //グラフの線より下側を塗りつぶさないようにする
                data: [12, 19, 3, 17, 6, 3, 7],  //縦軸の値
                borderColor: "#0066FF", //線の色
                backgroundColor: "#0066FF" //塗りつぶしの色
            }]
        },
        options: {
            title: {
                display: true, //タイトルの表示可否
                text: 'あなたの体重推移' //タイトル
            },
            scales: {
                yAxes: [{//縦軸のスケールを指定
                    ticks: {
                        suggestedMax: 75,//縦軸の最大値
                        suggestedMin: 65,//縦軸の最小値(最小値以下の値があれば自動で変更)
                        stepSize: 10,//縦軸の間隔
                        callback: function(value, index, values) {
                            return value + 'kg'
                        }
                    }
                }]
            },
        }
    });
</script>
グラフの表示結果

f:id:narunaru7638:20190129234524p:plain





配列のグラフ表示の方法

せっかくなので横軸やグラフ表示する値が決まったものではなく、何かしらの配列の情報を用いてグラフ表示したいと思います。
横軸に$periodという変数、グラフ表示する値に$periodをキーとした連想配列$period_dailyWeightを用いています。

<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
  type: 'line',
  data: {
    labels: [
    <?php
    $i=0;
    for($i = 0; $i < count($period); $i++){
      echo " ' ".$period[$i]." ' ".",";
    }
      ?>
    ],
    datasets: [{
      label: あなたの体重,
      lineTension: 0, //グラフの曲がり度合い(デフォルトは0.5)
      fill: false,    //グラフの線より下側を塗りつぶさないようにする
      data: [
        <?php
        $i=0;
        for($i = 0; $i < count($period); $i++){
          echo $period_dailyWeight[$period[$i]].",";
        }
          ?>
        ],
      borderColor: "#0066FF",//線の色
      backgroundColor: "#0066FF"//塗りつぶしの色
    }]
  },
  options: {
    title: {
      display: true,//タイトルの表示可否
      text: 'あなたの体重推移'//タイトル
    },
    scales: {
      yAxes: [{
        ticks: {
          suggestedMax: 75,
          suggestedMin: 65,
          stepSize: 10,
          callback: function(value, index, values){
          return  value +  'kg'
          }
        }
      }]
    },
  }
});
</script>
記述のポイント

変わった部分は横軸labelsとグラフ表示する値dataの部分となります。

***①PHPでif文を回す

「基本的なグラフ表示の方法」と同じような記載方法になるように、PHPでif文を回して、echo文で配列の中身を順番に呼び出しています。

***②「 , 」や「 ' 」を結合

「基本的なグラフ表示の方法」と同じような記載方法になるように、「 , 」や「 ' 」を結合しています。
「変数(文字列).変数(文字列)」で変数同士を結合できます。

***③「 , 」や「 ' 」を、「"」で囲う

「 , 」や「 ' 」は文字列なので、「"」でそれぞれ囲んでおります。

PHPで作ったWebサービスをネットに公開する

Webサービス(PHP+CSS+JS)をネットに公開する

せっかく作ったサービス、ネットに公開してみたいですよね。
Herokuというサービスを使って、Webサービスを公開していきます。
MySQLなどのデータベースと連携したサービスの公開方法ではありません。

前提

環境:Windows10、gitインストール済み


ステップ1:Herokuのアカウント登録

1-1:Herokuのトップページにアクセス

Heroku とは、PaaS(Platform as a Service)と呼ばれるサービスで、サーバコンピュ ータを提供してくれるサービスです。
まずは下記にアクセスしてアカウント登録をしましょう。
jp.heroku.com

1-2:アカウントの新規登録画面へ

アカウントの新規登録画面へ

f:id:narunaru7638:20190118225040j:plain
赤い枠で示した「無料で新規登録」をクリック

1-3:アカウント登録に必要な情報を入力

f:id:narunaru7638:20190118225211j:plain
アカウント登録に必要な情報を入力

適当にアカウント登録が出来たら次に進みましょう。


ステップ2:Heroku CLIのインストール

Heroku CLIをインストールして、「heroku」コマンドを使うことでアプリをデプロイしてきます。

2-1:Heroku CLIのダウンロード

下記サイトにアクセスしてHerokuCLIをダウンロード
devcenter.heroku.com

f:id:narunaru7638:20190118221344j:plain
自身のOSに合わせてダウンロード

2-2:Heroku CLIのインストール

ダウンロードしたファイルを実行して、インストールを行いましょう。


ステップ3:Herokuアプリの作成

3-1:プロジェクトフォルダへ移動
> cd \「自身のプロジェクトフォルダ」
3-2:Herokuへログイン
>heroku login

上記コマンドを実施した後に、Herokuに登録したメールアドレスとパスワードを入力してください。
下記のような表記が出れば成功です。

Logged in as 「Herokuに登録したアドレス」
3-3:Herokuアプリを作成

下記コマンドでHeroku上にアプリケーションを入れるための箱を用意します。

heroku create 「自身のアプリケーション名」

アプリケーション名は他の人と重複できません。
独自の名前をつけてください。
(heroku createだけで実施するとランダムなアプリ名となります。)


ステップ4:アプリのデプロイに必要なファイル等の作成

4-1:Gitリポジトリの新規作成

HerokuアプリはGitのリモートリポジトリとして、作成されます。
下記コマンドでまずgitリポジトリを新規作成しましょう。

>git init
4-2:リモートリポジトリの作成

下記コマンドでリモートリポジトリを作成します。

heroku git:remote -a 「自身のアプリケーション名」
4-3:git にリモートリポジトリとして 作成されたherokuの確認

git にリモートリポジトリとして heroku が作成されて います。リモートリポジトリを確認してみましょう。

>git remote -v
heroku  https://git.heroku.com/「自身のアプリケーション名」.git (fetch)
heroku  https://git.heroku.com/「自身のアプリケーション名」.git (push)

こんな感じになれば成功です。

4-4:composer.jsonの作成

プロジェクトフォルダに「composer.json」ファイルを作成しましょう。
ファイルの中身は以下の通り。(PHPのバージョンは自身のバージョンに合わせてください。)

{
  "require": {
    "php": "^7.3.0"
  }
}

PHPのバージョンは以下のコマンドで確認。
>php -v

4-5:composerのアップデート
composer update

問題なければ、「composer.lock」というファイルが出来ているはずです。

4-6:Procfileの作成

プロジェクトフォルダに「Procfile」(拡張子なし)というファイルを作成します。
ファイルの内容は下記の通り。
Procfile は、どのWebサーバを使うかという指定をしています。
下記で Heroku の apache2 サーバを利用する場合です。

web: vendor/bin/heroku‐php‐apache2 /
4-7:Gitのコミットを最新に

以下のコマンドを実施して作成したファイル等を含めたGitのコミットをします。

git add .
git commit -m "コミット名"

ステップ5:アプリのデプロイ

5-1:アプリのデプロイ

登録されたリモートリポジトリ heroku に対して、 git push を行うと、デ プロイできます。

git push heroku master

デプロイ中はいろいろ表示され、少し待ちますが、
最終的に以下のような表記がされれば成功です。

remote:        https://「自身のアプリケーション名」.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/「自身のアプリケーション名」.git
 * [new branch]      master -> master
5-2:公開されたアプリのURLにアクセス

下記のように自分で設定した Herokuアプリ名  の URL にアクセスしてみてください。

https://「自身のアプリケーション名」.herokuapp.com/「アクセスしたいphpファイル名」.php

JavaScriptでカウントダウンを表示して違法サイトっぽいページを作る

JavaScriptでカウントダウンを表示する

JavaScriptでは画面遷移することなく、画面の表示を変えることができます。
簡単にカウントダウンをするコードを書いてみます。

論よりコード

    //カウントダウンを開始する数を定義
    var count = 10;

    //カウンターを表示する箇所(class="show-count-text")のDOM(HTML)を取得する
    var counterNode = document.querySelector('.show-count-text');

    //カウントダウン関数を作成
    function CountDown() {
      count --;//カウントを減らす
      counterNode.innerText = count;//innerTextを使って取得したDOMの中身のテキストを書き換える
    }

    //1000m秒(=1秒)ごとにCouontDown関数を実施
    setInterval(CountDown, 1000);

簡単な解説

①カウントダウンを表示したい箇所のDOMを取得して、それをinnertextで書き換える関数を作成する
②setIntervalでカウントダウンをする関数を1秒おきに実施する



カウントダウンの使用例

せっかくなのでカウントダウンを活用して一つ簡単なサイトを作ってみようと思います。
せっかくなので面白くなるようにネットサーフィンしているとよく出会う違法サイトっぽいページを作ります。

javascriptのコード

window.addEventListener('DOMContentLoaded',
  function () {

    //カウントダウンを開始する数を定義
    var count = 10;
    //カウンターを表示する箇所(class="show-count-text")のDOM(HTML)を取得する
    var counterNode = document.querySelector('.show-count-text');

    alert('あなたのパソコンは攻撃を受けています。対策を見ますか?');

    //カウントダウン関数を作成
    function CountDown() {
      count --;//カウントを減らす
      counterNode.innerText = count;//innerTextを使って取得したDOMの中身のテキストを書き換える

      //countが0になると別サイトに誘導する
      if(count === 0){
        location.href = "BadSite.html" ;
      }
    }

    //1000m秒(=1秒)ごとにCouontDown関数を実施
    setInterval(CountDown, 1000);

  }, false
);

htmlとcss

一応オマケに適当に作成したhtmlとcssのコードです。

html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>ウイルスが検出されました</title>
    <link rel="stylesheet" type="text/css" href="style_VirusSite.css">
  </head>
  <body>
    <h1>ご使用のPCにウイルスが検出されました</h1>
      <!--class="show-count-text"の中身をjsで変更-->
      <p><strong><span class="show-count-text">10</span>秒以内</strong>に問題が解決されない場合、<br>ウイルスがPCに被害を及ぼし、データがすべて削除される可能性があります。</p>
      <p>下の手順に従って、ただちにウイルスを削除してください。</p>

      <p class="step">ステップ1:下のボタンをクリックして無料のウイルス対策ソフトをダウンロード</p>
      <p class="step">ステップ2:ウイルス対策ソフトをインストールし、PCをすぐにクリーンアップ</p>

      <!--ダウンロードをクリックすると違法サイトに転送-->
      <a href="BadSite.html">ウイルス対策ソフトをダウンロード</a>

      <script src="main_VirusSite.js"></script>
  </body>
</html>
CSS
h1{
  background-color: yellow;
  width:600px;
}
.step{
  color: blue;
}
a{
  text-decoration: none;
  color:white;
  background-color:green;
  padding:5px;
  margin-left:150px;
}
a:hover{
  text-decoration: underline;
}
strong{
  color: red;
}

以上で違法サイトの完成です。



完成サイトイメージ

ツイッターで公開している下記動画のようになればオッケーです。

MAMPのMySQLサーバが動かないときの対策(Windowsユーザ向け)

MAMPMySQLサーバが動かない

MAMPを起動してもMySQLサーバが動かないときがあります。
こんな状況ですね。

f:id:narunaru7638:20190106222659j:plain
MySQLサーバが起動しないときのMAMP画面

結論:XAMPPを使おう

身も蓋もないですが、これが最速でした。
エンジニアはMACユーザが多く、MAMPを推奨されて不安になると思いますが、XAMPPを使いましょう。
このあとに注意点をまとめます。


※以下、念のため私が対策した内容をまとめます。
 もしこちらでMAMPが利用できれば、それで良いです。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
mod_perlを無効化
http://onocom.net/blog/mampwindows%E3%81%AEmamp%E3%81%A7apache%E3%81%8C%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%AA%E3%81%84/

②ターミナルからMySQLを停止
https://manablog.org/mamp-mysql-error/

 ※コマンドはここ
 https://webkaru.net/mysql/windows-service-start-stop/

 ※システムエラー5が発生したとき
 http://www.bmoo.net/archives/2013/10/315083.html

④ポート番号競合
https://qiita.com/maximum80/items/3ca16b0b41cd5ff11c6c

 ※windowsでの確認方法
 https://www.engineer-memo.net/20090822-51

⑤モジュールエラー
https://qiita.com/maximum80/items/3ca16b0b41cd5ff11c6c

⑥設定ファイルの書き間違え
https://qiita.com/maximum80/items/3ca16b0b41cd5ff11c6c
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

結論:XAMPPの使い方と注意点

XAMPPのダウンロードおよび使い方

このサイトが参考になります。正直めちゃくちゃ簡単です。
https://techacademy.jp/magazine/1722

XAMPP利用時の注意点

MAMPと異なり、XAMPPでは「root」ユーザのパスワードが「空欄」となります。(MAMPの場合パスワードも「root」)


MAMP利用時と同じソースコードMySQLのDBに接続しようとすると以下のエラーが出ると思います。
Fatal error: Uncaught PDOException: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) in C:\xampp\htdocs\sample\index.php:81 Stack trace: #0 C:\xampp\htdocs\sample\index.php(81): PDO->__construct('mysql:dbname=ph...', 'root', 'root', Array) #1 {main} thrown in C:\xampp\htdocs\sample\index.php on line 81


以下、参考のソースコードです。「$password = '';」が変更した部分です。

$dsn = 'mysql:dbname=service_sample01;host=localhost;charset=utf8';
$user = 'root';
$password = '';
$options = array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
    );
$dbh = new PDO($dsn, $user, $password, $options);

git logコマンドを実施した際の文字化け

git log -pなどでの文字化け

git logなどの結果に日本語が含まれていると文字化けすることがある。

+<!DOCTYPE html>
+<html lang="ja">
+    <head>
+        <meta charset="utf-8">
+        <title>Git<E3><83><86><E3><82><B9><E3><83><88></title>
+    </head>
+    <body>
+        <h1><E3><83><90><E3><83><BC><E3><82><B8><E3><83><A7><E3><83><B3><E7><AE><A1><E7><90><86></h1>
+        <p>Git<E3><81><A7><E3><83><90><E3><83><BC><E3><82><B8><E3><83><A7><E3><83><B3><E7><AE><A1><E7><90><86>q</p>
+    </body>
+</html>

このような場合は、ページャの設定 (core.pager) に LESSCHARSET の設定を加えます。

>git config --global core.pager "LESSCHARSET=utf-8 less"

これで正しく表示されます。

+<!DOCTYPE html>
+<html lang="ja">
+    <head>
+        <meta charset="utf-8">
+        <title>Gitテスト</title>
+    </head>
+    <body>
+        <h1>バージョン管理</h1>
+        <p>Gitでバージョン管理q</p>
+    </body>
+</html>


ちなみに設定の確認と削除は以下

設定確認

>git config --global --list
user.name=TestUsers
user.email=TestUsers@gmail.com
core.pager=LESSCHARSET=utf-8 less

設定削除

>git config --global --unset core.pager

計算した割合が代入されていないように見える問題

勝率とか割合の計算のときに、計算結果が「0.0」となってしまう問題。
計算結果が代入されていないように見えて、わりとハマったのでメモ。

問題が発生した状況

「計算結果を表示するmainクラス」と「割合を計算するクラス」で実行。

計算結果を表示するmainクラス
package test;

public class BaseBallResult2 {

    public static void main(String[] args){

        BaseBallTeam2 team = new BaseBallTeam2();
        team.setName("なる");
        team.setWin(100);
        team.setLose(33);
        team.report();

    }
}
割合を計算するクラス
package test;

class BaseBallTeam2 {

    private String name;
    private int win;
    private int lose;

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public int getWin(){
        return win;
    }

    public void setWin(int win){
        this.win = win;
    }

    public int getLose(){
        return lose;
    }

    public void setLose(int lose){
        this.lose = lose;
    }

    public double getRate(){
        return (double)(this.win / (this.win + this.lose));
    }

    public void report(){
        System.out.println(this.name + "の成績は" + this.win + "勝" + this.lose + "敗、勝率は" + this.getRate() + "です");
    }

}
表示結果
なるの成績は100勝33敗、勝率は0.0です

プログラム自体は問題なく動いているのですが、勝率が「0.0」になってしまっています。


結論

実際は値が代入されていないのではなく、int型とdouble型の型変換の問題でした。

変更箇所

「割合を計算するクラス」の以下の箇所を変更。

        return (double)(this.win / (this.win + this.lose));

以下に変えただけです。

        return (double)this.win / (this.win + this.lose);
表示結果
なるの成績は100勝33敗、勝率は0.7518796992481203です


Javaでは int型とint型の計算ですと、答えが少数になるような結果でも少数が切り捨てられてしまう。今回の場合、小数の結果を切り捨て、int型の「0」になったあとにdouble型に変換しているので「0.0」という結果になったよう。これを回避するためには 、double型とint型の計算にするなど、片方の数値の型を変換する必要があるとのこと。動作自体はするので、なかなか問題が見つけられなかった…