2021年3月4日 星期四

建立在CentOS上的 docker 與 mongodb 介紹

 下一篇:如何用shell快速建立自己的docker-nginx-php-mysql開發環境

感恩陳瑩光老師指導!!

0.在VirtualBox 安裝 CentOS 7.8,並開啟 22 port
(01)開啟VirtualBox  22 port
(02)ssh 連線

1.在CentOS 安裝 docker
(01)解除安裝其他舊版本
$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
(02)建立REPOSITORY
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
(03)安裝docker
$ sudo yum install docker-ce docker-ce-cli containerd.io
(04)啟動docker
$ sudo systemctl start docker

現在我們將其寫成shell
檔案名稱:dockerInstall.sh
檔案內容:
#!/bin/bash
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
yum install -y yum-utils
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io
systemctl start docker


2.安裝 docker-compose
(01)安裝指令
$sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
(02)變更權限
sudo chmod +x /usr/local/bin/docker-compose
(03)版本
$sudo docker-compose version

現在我們將其寫成shell
檔案名稱:dockerComposeInstall.sh
檔案內容:
#!/bin/bash
curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose version


(01)安裝git
$sudo yum install git
(02)建立 test 目錄並進入test目錄
$sudo mkdir test
$cd test
$sudo git clone https://github.com/hamichen/docker-nginx-php-mysql.git
(04)到docker-nginx-php-mysql目錄下
$cd docker-nginx-php-mysql
(05)修改 docker-compose.yml
$sudo vi docker-compose.yml 
修改內容如下
version: '3'
services:
    web:
        image: nginx:alpine
        volumes:
            - "./etc/nginx/default.conf:/etc/nginx/conf.d/default.conf"
            - "./etc/ssl:/etc/ssl"
            - "./web:/var/www/html"
            - "./etc/nginx/default.template.conf:/etc/nginx/conf.d/default.template"
        ports:
            - "8000:80"    改為 - "80:80"
            - "3000:443"  改為 - "443:443"
        environment:
            - NGINX_HOST=${NGINX_HOST}
        command: /bin/sh -c "envsubst '$$NGINX_HOST' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
        restart: always
        depends_on:
            - php
            - mysqldb
    php:
        build:
            context: ./fpm
        restart: always
        volumes:
            - "./etc/php/php.ini:/usr/local/etc/php/conf.d/php.ini"
            - "./web:/var/www/html"
後來可改寫,不需重新build
    php:
        image: hamichen/php-fpm-7.3.14
        restart: always
        volumes:
             - "./etc/php/php.ini:/usr/local/etc/php/conf.d/php.ini"
            - "./web:/var/www/html"     

    memcached:
        image: memcached
        restart: always

    mongodb:
        image: library/mongo:3.4.9
        volumes:
           - ./data/mongodb:/data/db
           - /etc/localtime:/etc/localtime:ro
        ports:
           - "27117:27017"   改為  - "27017:27017" 
        restart: always
        privileged: true

    myadmin:
        image: phpmyadmin/phpmyadmin
        container_name: phpmyadmin
        ports:
            - "8080:80"
        environment:
            - PMA_ARBITRARY=1
            - PMA_HOST=${MYSQL_HOST}
        restart: always
        depends_on:
            - mysqldb
    mysqldb:
        image: mysql:${MYSQL_VERSION}
        container_name: ${MYSQL_HOST}
        restart: always
        env_file:
            - ".env"
        environment:
            - MYSQL_DATABASE=${MYSQL_DATABASE}
            - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
            - MYSQL_USER=${MYSQL_USER}
            - MYSQL_PASSWORD=${MYSQL_PASSWORD}
        ports:
            - "8989:3306"  改為  - "3306:3306" 
        command: mysqld --sql_mode=""  停用mysql 嚴格模式
        volumes:
            - "./data/db/mysql:/var/lib/mysql"
(06)修改.env
$sudo vi .env
修改內容如下:
# See https://docs.docker.com/compose/environment-variables/#the-env-file

# Nginx
NGINX_HOST=localhost

# PHP

# See https://hub.docker.com/r/nanoninja/php-fpm/tags/
PHP_VERSION=latest

# MySQL
MYSQL_VERSION=5.7.22
MYSQL_HOST=mysql
MYSQL_DATABASE=test
MYSQL_ROOT_USER=root
MYSQL_ROOT_PASSWORD=root 改為root的密碼 aa123456
MYSQL_USER=dev                          
MYSQL_PASSWORD=dev           docker     改為dev的密碼 aa123456

(07)依據 docker-compose.yml 內的定義,依序啟動多個 container ,以及建立它們之間的關連。
$sudo docker-compose up -d
注意事項:若網路連接時超時,中斷。可再下 $sudo docker-compose up -d,直到完成。

(08)檢查多個container 狀態
$sudo docker-compose ps
(09)開啟VirtualBox  80、8088 port 與網頁瀏覽http://127.0.0.1 與http://127.0.0.1:8080 



(10)關閉、重啟、啟動 docker 內的mysql 服務
$sudo docker stop mysql
$sudo docker restart mysql
$sudo docker start mysql
(11)在docker 內加入redis服務
到此複製
貼到docker-compose.yml,其內容如下,並修改:
version: '3'
services:
    web:
        image: nginx:alpine
        volumes:
            - "./etc/nginx/default.conf:/etc/nginx/conf.d/default.conf"
            - "./etc/ssl:/etc/ssl"
            - "./web:/var/www/html"
            - "./etc/nginx/default.template.conf:/etc/nginx/conf.d/default.template"
        ports:
            - "80:80"
            - "443:443"
        environment:
            - NGINX_HOST=${NGINX_HOST}
        command: /bin/sh -c "envsubst '$$NGINX_HOST' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
        restart: always
        depends_on:
            - php
            - mysqldb
    php:
        image: hamichen/php-fpm-7.3.14
        restart: always
        volumes:
            - "./etc/php/php.ini:/usr/local/etc/php/conf.d/php.ini"
            - "./web:/var/www/html"
    memcached:
        image: memcached
        restart: always

    mongodb:
        image: library/mongo:3.4.9
        volumes:
           - ./data/mongodb:/data/db
           - /etc/localtime:/etc/localtime:ro
        ports:
            - "27017:27017" 
        restart: always
        privileged: true

    myadmin:
        image: phpmyadmin/phpmyadmin
        container_name: phpmyadmin
        ports:
            - "8080:80"
        environment:
            - PMA_ARBITRARY=1
            - PMA_HOST=${MYSQL_HOST}
        restart: always
        depends_on:
            - mysqldb
    mysqldb:
        image: mysql:${MYSQL_VERSION}
        container_name: ${MYSQL_HOST}
        restart: always
        env_file:
            - ".env"
        environment:
            - MYSQL_DATABASE=${MYSQL_DATABASE}
            - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
            - MYSQL_USER=${MYSQL_USER}
            - MYSQL_PASSWORD=${MYSQL_PASSWORD}
        ports:
            - "3306:3306" 
       command: mysqld --sql_mode=""
        volumes:
            - "./data/db/mysql:/var/lib/mysql"
    redis: 
        image: redis:4.0.8-alpine
        container_name: db-redis
        restart: always
        ports:
            - "6379:6379"
        networks:  刪除
            - net_db 刪除
        volumes:
            - ./redis/config:/docker/config
            - ./redis/data:/data
        command: redis-server /docker/config/redis.conf    (14)刪除

(12)利用docker-compose up -d --build ,將redis加入docker 服務,並啟動。
$sudo docker-compose up -d --build
$sudo docker-compose ps


(13)檢查狀態
$sudo docker logs db-redis
發現無法打開 /docker/config/redis.conf
檢查無此檔案
所以在docker-compose.yml刪除         command: redis-server /docker/config/redis.conf    
重新下指令
$sudo docker-compose up -d --build
看所有container 是否被執行起來
$sudo docker-compose ps

將所有服務停止
$sudo docker-compose down
 


5.Mongodb 教學
(1)執行docker 內的mongodb
 docker exec -it docker-nginx-php-mysql_mongodb_1 mongo
(2)秀出資料庫
>show dbs;
(3)建立資料庫test
>use test;
(4)使用 insert 指令將一些資料輸入到 restaurants 這個 collection
>db.restaurants.insert(
  {
    "address" : {
      "street" : "2 Avenue",
      "zipcode" : "10075",
      "building" : "1480",
      "coord" : [ -73.9557413, 40.7720266 ],
    },
    "borough" : "Manhattan",
    "cuisine" : "Italian",
    "grades" : [
      {
        "date" : ISODate("2014-10-01T00:00:00Z"),
        "grade" : "A",
        "score" : 11
      },
      {
        "date" : ISODate("2014-01-16T00:00:00Z"),
        "grade" : "B",
        "score" : 17
      }
    ],
    "name" : "Vella",
    "restaurant_id" : "41704620"
  }
)
(5)查詢資料,指定資料庫test,使用 find指令
>db.restaurants.find();
(6)使用大於($gt)、小於($lt)指定查詢條件
>db.restaurants.find( { "grades.score": { $gt: 30 } } )

>db.restaurants.find( { "grades.score": { $lt: 30 } } )

(7)使用多個條件,$and 與 $or
>db.restaurants.find( { $or: [ { "cuisine": "Italian" }, { "address.zipcode": "10075" } ] } );

>db.restaurants.find( { $and: [ { "cuisine": "Italian" }, { "address.zipcode": "10075" } ] } );

(8)查詢結果排序
遞增排序,1 代表遞增
>db.restaurants.find().sort( { "borough": 1 } )
遞減排序,-1 代表遞減
>db.restaurants.find().sort( { "borough": -1 } )
先以"borough"條件遞增,後以"address.zipcode"條件遞增
db.restaurants.find().sort( { "borough": 1,"address.zipcode": 1 } )

(9)列出所有的 collections,共三種方法
>show collections;
>show tables;
>db.getCollectionNames();

(10)查詢整個 MongoDB 中所儲存的資料量大小
db.stats();

6.rodo 3t gui 工具 (安裝windows版本),安裝的機器IP為192.168.1.155
連接的port為 27017。所以設定為192.168.1.155:27017
(1)下載並安裝
接下來,就是[下一步]到安裝結束。
(2)對程式捷徑點兩下,就可以開始設定

設定完成,就可看到mongodb的資料庫架構

(3)mongodb的資料庫操作

(4)對 collection "restaurants",再insert 一筆資料。
db.restaurants.insert(
  {
    "address" : {
      "street" : "2333 Avenue",
      "zipcode" : "100759",
      "building" : "1480",
      "coord" : [ -73.9557413, 40.7720266 ],
    },
    "borough" : "Manha333ttan",
    "cuisine" : "Italian",
    "grades" : [
      {
        "date" : ISODate("2014-10-01T00:00:00Z"),
        "grade" : "A",
        "score" : 11
      },
      {
        "date" : ISODate("2014-01-16T00:00:00Z"),
        "grade" : "B",
        "score" : 17
      }
    ],
    "name" : "Vella",
    "restaurant_id" : "41704620"
  }
);

(5)下指令
>db.getCollection('restaurants').find();






如何在linux shell 交互環境下,自動填入密碼

 


1.安裝expect
sudo apt-get install expect

2.建立test.exp
$sudo pico test.exp

目的:利用帳號 webadmin 密碼 demo1234 從192.168.1.150 用ssh連線到 192.168.1.157

檔案名稱:test.exp
檔案內容
#!/usr/bin/expect          
set user "webadmin"          
set pwd "demo1234"
set host "192.168.1.157"

set timeout -1
spawn ssh -p 22 $user@$host
expect {
    "password: " {send "$pwd\r"}
}
expect "]*"                
send "touch /home/webadmin/aa.txt\r"
expect "]*"
send "echo hello world >> /home/webadmin/aa.txt\r"
expect "]*"             
interact

3.變更權限
$sudo chmod 777 test.exp

4.執行 test.exp
$sudo expect test.exp





2021年3月3日 星期三

紀明村老師的運動檢錄系統程式碼研究心得(一)介接CloudSchool與mysql資料庫

整理:
1.只要會用滑鼠點兩下,用shell 在 ubuntu 16.04 x64 桌面版本快速安裝 運動檢錄系統
https://skjhcreator.blogspot.com/2021/03/shell-ubuntu-1604-x64.html
2.紀明村老師運動會競賽檢錄系統更新模組_學生帳號管理模組
https://skjhcreator.blogspot.com/2021/03/blog-post.html
3.二林國小紀明村老師的二林網管 PDO + SQLite 程式寫作工具箱2014.07
https://skjhcreator.blogspot.com/2021/03/pdo-sqlite-201407.html
4.用shell 在CentOS 7 minimal 64位元 安裝 紀明村老師的運動會檢錄系統
https://skjhcreator.blogspot.com/2021/02/shell-centos-7-minimal-64.html
5.紀明村老師的運動檢錄系統程式碼研究心得(一)介接CloudSchool與mysql資料庫
https://skjhcreator.blogspot.com/2021/03/cloudschoolmysql.html
6.紀明村老師運動檢錄系統程式碼研究心得(二)登入login登出logout與使用者認證
https://skjhcreator.blogspot.com/2021/02/loginlogout.html
7.紀明村老師運動檢錄系統程式碼研究心得(三)smarty
https://skjhcreator.blogspot.com/2021/02/smarty.html



        現在研究紀老師的運動檢錄系統程式碼,心中湧起幾個問題。希望能藉由原始碼解決心中的疑惑。由於紀老師使用Sqlite,但內容也有mysql pdo的語法。因此,希望能改寫成mysql的語法。
1.安裝mysql
$sudo apt-get install mysql-server -y
$sudo apt-get install mysql-client -y
$sudo apt-get install libmysqlclient-dev -y

2.安裝phpmyadmin
$sudo apt-get install phpmyadmin -y

一、如何跟CloudSchool的API介接?
       2.介接之後,要如何處理資料?

檔案名稱:ApiGetData.php
檔案內容:
<?php
// 3.雲端學籍系統內,學校的 API ID
$API_client_id = '學校的 API ID';

// 4.雲端學籍系統內,學校的 API 密碼
$API_client_secret = '學校的 API 密碼';

//取得API資料
$GetApiData = elps_API();

//印出API資料
PP($GetApiData);

function elps_API(){
global $API_client_id,$API_client_secret;

// =================================================
//    學生榮譽榜 (url: https://api.chc.edu.tw)
//    校務佈告欄 (url: https://api.chc.edu.tw/school-news)
//    同步學期資料 (url: https://api.chc.edu.tw/semester-data)
//    更改師生密碼 (url: https://api.chc.edu.tw/change-password)

// API NAME
$api_name = '/semester-data';
//$api_name = '/school-news';
// 更改師生密碼 (url: https://api.chc.edu.tw/change-password)

// API URL
$api_url = 'https://api.chc.edu.tw';
//: https://api.chc.edu.tw/school-news
// 建立 CURL 連線
$ch = curl_init();
// 取 access token
curl_setopt($ch, CURLOPT_URL, $api_url."/oauth?authorize");
// 設定擷取的URL網址
curl_setopt($ch, CURLOPT_POST, TRUE);
// the variable
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'client_id' => $API_client_id,
'client_secret' => $API_client_secret,
'grant_type' => 'client_credentials'
));

$data = curl_exec($ch);
$data = json_decode($data);

$access_token = $data->access_token;
$authorization = "Authorization: Bearer ".$access_token;

curl_setopt($ch, CURLOPT_URL, $api_url.$api_name);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , $authorization )); // **Inject Token into Header**
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$result = curl_exec($ch);
return $result;
}
/* 列印變數*/
function PP($a){
echo "<pre>";print_r($a);
echo "</pre>";exit;
}

?>
若不在學校IP範圍內,則打開瀏覽器,測試ApiGetData.php。會出現此訊息如下:
若在學校IP範圍內,則打開瀏覽器,測試ApiGetData.php。會出現此訊息如下:
則會取得資料。

       2.介接之後,要如何處理資料?
          (1).檢查指定的檔案是否存在?
          (1).Y. 檔案存在,則取檔案資料
          (1).N.檔案不存在,則將取得的資料存入檔案
檔案名稱:ApiGetData2File.php
檔案內容:
<?php
// 3.雲端學籍系統內,學校的 API ID
$API_client_id = '學校的 API ID';

// 4.雲端學籍系統內,學校的 API 密碼
$API_client_secret = '學校的 API 密碼';

// 5.可寫入目錄(放置資料庫檔及暫存區用),建議搬至網頁目錄外
define('__SiteData', dirname(__file__).'/Sport_data/');
// define('__SiteData', '/home/webadmin/sport_data/');
// define('__SiteData', '/home/stu/data/');

//取得API資料
$GetApiData = API_data();

//印出API資料
PP($GetApiData);


function elps_API(){
global $API_client_id,$API_client_secret;

// =================================================
//    學生榮譽榜 (url: https://api.chc.edu.tw)
//    校務佈告欄 (url: https://api.chc.edu.tw/school-news)
//    同步學期資料 (url: https://api.chc.edu.tw/semester-data)
//    更改師生密碼 (url: https://api.chc.edu.tw/change-password)

// API NAME
$api_name = '/semester-data';
//$api_name = '/school-news';
// 更改師生密碼 (url: https://api.chc.edu.tw/change-password)

// API URL
$api_url = 'https://api.chc.edu.tw';
//: https://api.chc.edu.tw/school-news
// 建立 CURL 連線
$ch = curl_init();
// 取 access token
curl_setopt($ch, CURLOPT_URL, $api_url."/oauth?authorize");
// 設定擷取的URL網址
curl_setopt($ch, CURLOPT_POST, TRUE);
// the variable
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'client_id' => $API_client_id,
'client_secret' => $API_client_secret,
'grant_type' => 'client_credentials'
));

$data = curl_exec($ch);
$data = json_decode($data);

$access_token = $data->access_token;
$authorization = "Authorization: Bearer ".$access_token;

curl_setopt($ch, CURLOPT_URL, $api_url.$api_name);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , $authorization )); // **Inject Token into Header**
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$result = curl_exec($ch);
return $result;
}

/* 7.更新處理函式  */
function API_data(){
                //所在的目錄__SiteData及檔案名稱為date("Y").'_elps.txt'
$file = __SiteData.date("Y").'_elps.txt';
//echo $file;
if (file_exists($file)) {
$sch_json=file_get_contents($file);
}else{
$sch_json=elps_API();
$num=file_put_contents($file,$sch_json);//寫入echo $num;
}
$arr = json_decode($sch_json);
return $arr;
}

/*自動建立目錄*/
function autoDir($dir){
//echo $dir.'<br>';
if (file_exists($dir) && is_dir($dir)) return ;
    $rs = @mkdir($dir, 0755); 
if (!$rs) backe($dir."<br>資料存放區不存在或無法建立!");
}

/* 列印變數*/
function PP($a){
echo "<pre>";print_r($a);
echo "</pre>";exit;
}

##################回上頁函式1#####################
function backe($value= "BACK"){
//echo head();
echo  "<meta charset='UTF-8'><br><br><CENTER>";
echo "<h4>--== 《系統訊息》 ==--</h4>";
echo "<div align=center onclick='history.back();' style='font-size:12pt;color:#A52A2A;'><b>";
echo $value;
echo "</b><BR></div><h5 onclick='history.back();'>--==  《按下後返回》 ==--</h5>";
exit;
}

?>

二、介接之後,如何取得的資料存入資料庫中?
   1.如何用pdo建立資料庫?
   2.如何用pdo建立資料表?
   3.介接cloudschool之後,取得的資料,如何存入資料表內?
   
資料表stud

   1.如何用pdo建立資料庫?
檔案名稱:PdoCreateDatabase.php
檔案內容:
<?php
$school_code='教育部學校代碼';
$MySQL['Host']='localhost';
$MySQL['User']='資料庫使用者';
$MySQL['Pass']='資料庫密碼';
$MySQL['Db']='Sport109_'.$school_code;
try {
//建立資料庫
    $CONN =new PDO('mysql:host='.$MySQL['Host'], $MySQL['User'] ,$MySQL['Pass']);
    $SQL="CREATE DATABASE".$MySQL['Db']."CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;";
    $CONN->exec($SQL) or die($SQL);
    backe("!!資料庫 ".$MySQL['Db']." OK!!");
 }
 catch (Exception $e) 
 {
       backe("!!無法連結資料庫!!");
       //die("<center><h2>無法連結資料庫</h2></center>");

##################回上頁函式1#####################
function backe($value= "BACK"){
//echo head();
echo  "<meta charset='UTF-8'><br><br><CENTER>";
echo "<h4>--== 《系統訊息》 ==--</h4>";
echo "<div align=center onclick='history.back();' style='font-size:12pt;color:#A52A2A;'><b>";
echo $value;
echo "</b><BR></div><h5 onclick='history.back();'>--==  《按下後返回》 ==--</h5>";
exit;
}
?>

     2.如何用pdo建立資料表?
       (1).先檢查是否可從資料表取出一筆資料?
       (1).Y.取得出,表示有此資料表->不建立資料表
       (1).N.取不出,表示無此資料表->建立資料表
檔案名稱:PdoCreateTable.php
檔案內容:
<?php
$school_code='教育部學校代碼';
$MySQL['Host']='localhost';
$MySQL['User']='資料庫使用者';
$MySQL['Pass']='資料庫密碼';
$MySQL['Db']='Sport109_'.$school_code;

/*建立連結*/
try {
// for MySQL
$CONN =new PDO('mysql:host='.$MySQL['Host'].';dbname='.$MySQL['Db'], $MySQL['User'],$MySQL['Pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"));
    }
catch (Exception $e) 
    {
       backe("!!無法連結資料庫!!");
       //die("<center><h2>無法連結資料庫</h2></center>");
 }
/* 建立 stud 資料表*/
        $SQL1="select * from `stud` limit 1";
        $SQL2="CREATE TABLE `stud`(
                      `id` INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                      `stuid` VARCHAR(10) NOT NULL UNIQUE,
                      `stuname` TEXT NOT NULL,
                      `idclass` TEXT NOT NULL,
                      `cla` TEXT NOT NULL,
                      `seatnum` INT(10) DEFAULT '0',
                      `sex` TEXT NOT NULL,
                      `edukey` TEXT,
                      `created` TEXT,
                      `modify` TEXT
                      );";
                $rs=$CONN->query($SQL1);
                if (!$rs) {
                        $rs=$CONN->query($SQL2) or die($SQL2);
                } else {
                        backe('Had stud 資料表!');
                }
##################回上頁函式1#####################
function backe($value= "BACK"){
//echo head();
echo  "<meta charset='UTF-8'><br><br><CENTER>";
echo "<h4>--== 《系統訊息》 ==--</h4>";
echo "<div align=center onclick='history.back();' style='font-size:12pt;color:#A52A2A;'><b>";
echo $value;
echo "</b><BR></div><h5 onclick='history.back();'>--==  《按下後返回》 ==--</h5>";
exit;
}

?>

需要注意的是,同樣是建立資料表stud,建立資料表的語法會有些微不同
MYSQL語法:
CREATE TABLE `stud`(
  `id` INTEGER AUTO_INCREMENT PRIMARY KEY,
  `stuid` VARCHAR(20) NOT NULL UNIQUE,
  `stuname` TEXT NOT NULL,
  `idclass` TEXT NOT NULL,
  `cla` TEXT NOT NULL,
  `seatnum` INTEGER DEFAULT '0',
  `sex` TEXT NOT NULL,
  `edukey` TEXT,
  `created` TEXT,
  `modify` TEXT
);

Sqlite語法:
CREATE TABLE `stud`(
  `id` INTEGER AUTO_INCREMENT PRIMARY KEY,
  `stuid` TEXT NOT NULL UNIQUE,
  `stuname` TEXT NOT NULL,
  `idclass` TEXT NOT NULL,
  `cla` TEXT NOT NULL,
  `seatnum` INTEGER DEFAULT '0',
  `sex` TEXT NOT NULL,
  `edukey` TEXT,
  `created` TEXT,
  `modify` TEXT
);
    
   3.介接cloudschool之後,取得的資料,如何存入資料表內?
      (1).在已建立資料庫、資料表,只剩下將取得的資料,存入資料表前提下。
      (2).在建立資料庫之後。需建立資料表,並將取得的資料,存入資料表前提下。

      (1).在已建立資料庫、資料表,只剩下將取得的資料,存入資料表前提下。
檔案名稱:ApiData2Table01.php
檔案內容:
<?php
$school_code='教育部學校代碼';
$MySQL['Host']='localhost';
$MySQL['User']='資料庫使用者';
$MySQL['Pass']='資料庫密碼';
$MySQL['Db']='Sport109_'.$school_code;

// 5.可寫入目錄(放置資料庫檔及暫存區用),建議搬至網頁目錄外
define('__SiteData', dirname(__file__).'/Sport_data/');
// define('__SiteData', '/home/webadmin/sport_data/');
// define('__SiteData', '/home/stu/data/');

/*建立連結*/
try {
// for MySQL
$CONN =new PDO('mysql:host='.$MySQL['Host'].';dbname='.$MySQL['Db'], $MySQL['User'],$MySQL['Pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"));
    }
catch (Exception $e) 
    {
       backe("!!無法連結資料庫!!");
       //die("<center><h2>無法連結資料庫</h2></center>");
 }

//取得API資料
$arr=API_data();

//PP($arr);
//將取得的資料,存入資料表
add_stud($arr);

/* 7.更新處理函式  */
function API_data(){
                //所在的目錄__SiteData及檔案名稱為date("Y").'_elps.txt'
$file = __SiteData.date("Y").'_elps.txt';
//echo $file;
if (file_exists($file)) {
$sch_json=file_get_contents($file);
}else{
//$sch_json=elps_API();
//$num=file_put_contents($file,$sch_json);//寫入echo $num;
}
$arr = json_decode($sch_json);
return $arr;
}

/*加入學生資料*/
function add_stud($arr){
if (!isset($arr->學期編班)) return ;
foreach($arr->學期編班 as $obj){
/* 判斷有沒有學生 */
if (isset($obj->學期編班)) {
//echo $obj->年級.'-'.$obj->班序.'人數'.count($obj->學期編班).'<br>';
foreach($obj->學期編班 as $ary){
$created=date("Y-d-m H:i:s");
$stuid=$ary->學號;
$seatnum=$ary->座號;
$stuname=$ary->姓名;
$sex=$ary->性別;
$edukey=$ary->身分證編碼;
$cla=$obj->年級.'_'.$obj->班序;
$idclass=$obj->年級.sprintf("%02d",$obj->班序).sprintf("%02d",$ary->座號);
$SQL="INSERT INTO `stud` (stuid , stuname , idclass , cla , seatnum , sex , edukey , created) values ('{$stuid}' ,'{$stuname}' ,'{$idclass}' ,'{$cla}' ,'{$seatnum}' ,'{$sex}' ,'{$edukey}' ,'{$created}')";
//echo $SQL."<br>";
$rs=$CONN->query($SQL);// or die($SQL);
}
}
}
}

/* 列印變數*/
function PP($a){
echo "<pre>";print_r($a);
echo "</pre>";exit;
}

?>

      (2).在建立資料庫之後。需建立資料表,並將取得的資料,存入資料表前提下。
檔案名稱:ApiData2Table02.php
檔案內容:
<?php
$school_code='教育部學校代碼';
$MySQL['Host']='localhost';
$MySQL['User']='資料庫使用者';
$MySQL['Pass']='資料庫密碼';
$MySQL['Db']='Sport109_'.$school_code;

// 3.雲端學籍系統內,學校的 API ID
$API_client_id = '學校的 API ID';

// 4.雲端學籍系統內,學校的 API 密碼
$API_client_secret = '學校的 API 密碼';

// 5.可寫入目錄(放置資料庫檔及暫存區用),建議搬至網頁目錄外
define('__SiteData', dirname(__file__).'/Sport_data/');
// define('__SiteData', '/home/webadmin/sport_data/');
// define('__SiteData', '/home/stu/data/');

/*建立連結*/
try {
// for MySQL
$CONN =new PDO('mysql:host='.$MySQL['Host'].';dbname='.$MySQL['Db'], $MySQL['User'],$MySQL['Pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"));
    }
catch (Exception $e) 
    {
       backe("!!無法連結資料庫!!");
       //die("<center><h2>無法連結資料庫</h2></center>");
 }

/* 建立 stud 資料表*/
        $SQL1="select * from `stud` limit 1";
        $SQL2="CREATE TABLE `stud`(
                      `id` INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                      `stuid` VARCHAR(10) NOT NULL UNIQUE,
                      `stuname` TEXT NOT NULL,
                      `idclass` TEXT NOT NULL,
                      `cla` TEXT NOT NULL,
                      `seatnum` INT(10) DEFAULT '0',
                      `sex` TEXT NOT NULL,
                      `edukey` TEXT,
                      `created` TEXT,
                      `modify` TEXT
                      );";
                $rs=$CONN->query($SQL1);
                if (!$rs) {
                        //建立資料表stud
                        $rs=$CONN->query($SQL2) or die($SQL2);
                         //取得API資料
                         $arr=API_data();
                         //將取得的資料,存入資料表
                         add_stud($arr);
                         backe('資料表建立OK! API資料存入資料表!');
                } else {
                        //取得API資料
                         $arr=API_data();
                         //將取得的資料,存入資料表
                         add_stud($arr);
                        backe('已有資料表!API資料存入資料表!');
                }

function elps_API(){
global $API_client_id,$API_client_secret;

// =================================================
//    學生榮譽榜 (url: https://api.chc.edu.tw)
//    校務佈告欄 (url: https://api.chc.edu.tw/school-news)
//    同步學期資料 (url: https://api.chc.edu.tw/semester-data)
//    更改師生密碼 (url: https://api.chc.edu.tw/change-password)

// API NAME
$api_name = '/semester-data';
//$api_name = '/school-news';
// 更改師生密碼 (url: https://api.chc.edu.tw/change-password)

// API URL
$api_url = 'https://api.chc.edu.tw';
//: https://api.chc.edu.tw/school-news
// 建立 CURL 連線
$ch = curl_init();
// 取 access token
curl_setopt($ch, CURLOPT_URL, $api_url."/oauth?authorize");
// 設定擷取的URL網址
curl_setopt($ch, CURLOPT_POST, TRUE);
// the variable
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'client_id' => $API_client_id,
'client_secret' => $API_client_secret,
'grant_type' => 'client_credentials'
));

$data = curl_exec($ch);
$data = json_decode($data);

$access_token = $data->access_token;
$authorization = "Authorization: Bearer ".$access_token;

curl_setopt($ch, CURLOPT_URL, $api_url.$api_name);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , $authorization )); // **Inject Token into Header**
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$result = curl_exec($ch);
return $result;
}

/* 7.更新處理函式  */
function API_data(){
                //所在的目錄__SiteData及檔案名稱為date("Y").'_elps.txt'
$file = __SiteData.date("Y").'_elps.txt';
//echo $file;
if (file_exists($file)) {
$sch_json=file_get_contents($file);
}else{
$sch_json=elps_API();
$num=file_put_contents($file,$sch_json);//寫入echo $num;
}
$arr = json_decode($sch_json);
return $arr;
}

/*加入學生資料*/
function add_stud($arr){
if (!isset($arr->學期編班)) return ;
foreach($arr->學期編班 as $obj){
/* 判斷有沒有學生 */
if (isset($obj->學期編班)) {
//echo $obj->年級.'-'.$obj->班序.'人數'.count($obj->學期編班).'<br>';
foreach($obj->學期編班 as $ary){
$created=date("Y-d-m H:i:s");
$stuid=$ary->學號;
$seatnum=$ary->座號;
$stuname=$ary->姓名;
$sex=$ary->性別;
$edukey=$ary->身分證編碼;
$cla=$obj->年級.'_'.$obj->班序;
$idclass=$obj->年級.sprintf("%02d",$obj->班序).sprintf("%02d",$ary->座號);
$SQL="INSERT INTO `stud` (stuid , stuname , idclass , cla , seatnum , sex , edukey , created) values ('{$stuid}' ,'{$stuname}' ,'{$idclass}' ,'{$cla}' ,'{$seatnum}' ,'{$sex}' ,'{$edukey}' ,'{$created}')";
//echo $SQL."<br>";
$rs=$CONN->query($SQL);// or die($SQL);
}
}
}
}

/* 列印變數*/
function PP($a){
echo "<pre>";print_r($a);
echo "</pre>";exit;
}

##################回上頁函式1#####################
function backe($value= "BACK"){
//echo head();
echo  "<meta charset='UTF-8'><br><br><CENTER>";
echo "<h4>--== 《系統訊息》 ==--</h4>";
echo "<div align=center onclick='history.back();' style='font-size:12pt;color:#A52A2A;'><b>";
echo $value;
echo "</b><BR></div><h5 onclick='history.back();'>--==  《按下後返回》 ==--</h5>";
exit;
}

?>











 

紀明村老師運動會競賽檢錄系統更新模組_學生帳號管理模組

整理:
1.只要會用滑鼠點兩下,用shell 在 ubuntu 16.04 x64 桌面版本快速安裝 運動檢錄系統
https://skjhcreator.blogspot.com/2021/03/shell-ubuntu-1604-x64.html
2.紀明村老師運動會競賽檢錄系統更新模組_學生帳號管理模組
https://skjhcreator.blogspot.com/2021/03/blog-post.html
3.二林國小紀明村老師的二林網管 PDO + SQLite 程式寫作工具箱2014.07
https://skjhcreator.blogspot.com/2021/03/pdo-sqlite-201407.html
4.用shell 在CentOS 7 minimal 64位元 安裝 紀明村老師的運動會檢錄系統
https://skjhcreator.blogspot.com/2021/02/shell-centos-7-minimal-64.html
5.紀明村老師的運動檢錄系統程式碼研究心得(一)介接CloudSchool與mysql資料庫
https://skjhcreator.blogspot.com/2021/03/cloudschoolmysql.html
6.紀明村老師運動檢錄系統程式碼研究心得(二)登入login登出logout與使用者認證
https://skjhcreator.blogspot.com/2021/02/loginlogout.html
7.紀明村老師運動檢錄系統程式碼研究心得(三)smarty
https://skjhcreator.blogspot.com/2021/02/smarty.html


使用方法:
1.手動更新:
    假設伺服主機IP:172.20.3.7,帳號:webadmin 
    競賽檢錄系統安裝位置為/home/webadmin/html/Sport109/
    (1)使用Filezilla將檔案上傳到伺服主機


    (2)使用putty.exe 連線到172.20.3.7
                                        
                                        
    (3)指令操作
         (i)安裝zip與unzip(若有則免裝)
         $sudo apt-get install zip unzip -y

         (ii)解壓Sport109_StudAccManager20201106.zip 並更名為StudAccManager
         $sudo unzip Sport109_StudAccManager20201106.zip
         $sudo mv Sport109_StudAccManager20201106 StudAccManager

         (iii)競賽檢錄系統的menu.php更改名稱為menu_old.php
         $sudo mv ~/html/Sport109/menu.php  ~/html/Sport109/menu_old.php

         (iv)將StudAccManager內5個檔案複製到競賽檢錄系統
         $sudo cp StudAccManager/menu.php student.* student_cla.* ~/html/Sport109/

          寫到這裡,突然懷念起以前SFS3,一鍵就能模組更新。還有 git 的方法(git clone)。

     (4)網頁開啟,並登入。可看到
        

只要點兩下,就能將input資料夾內所有m4a 轉檔為 mp3

         最近需要將m4a檔案轉檔為mp3,所以寫python程式來處理。希望將很多的m4a放進input資料夾內,只要點兩下滑鼠就能將這些m4a 通通轉檔為 mp3。          Recently, I needed to convert M4A files in...