- 投稿日:2020-03-20T23:50:27+09:00
【Laravel】配列取り出し方パターン
単純配列
単純配列$memo[] = array(); $memo = [100,200,300,400,500]; $data = $memo[2]; echo $data; //300連想配列$memo[] = array(); $memo = [ 'counry' => 'Japan', 'capital' => 'Tokyo', 'population' => 120000000 ]; $data = $memo['capital']; echo $data; //Tokyo連想配列(value値が複数)$memo[] = array(); $memo = [ 'country' => ['Japan', 'China', 'Korea'], 'capital' => ['Tokyo', 'Beigin', 'Sore'] ]; $data = $memo['capital'][1]; echo $data; //Beigin多次元配列$memo[] = array(); $memo = [ ['田中', '兵庫', 26], ['斎藤', '京都', 30], ['鈴木', '徳島', 43] ]; foreach($memo as $value) { $memos = $value[0].'('.$value[1].'県出身'.$value[2].'才'.')'; echo '<br>'; } //"田中(兵庫県出身26才)" //"斎藤(京都県出身30才)" //"鈴木(徳島県出身43才)"多次元配列$memo[] = array(); $memo = array( '東京' => [ '世田谷区'=>'100', '渋谷区'=>'255', '町田市'=>'1731', ], '北海道' => [ '札幌市'=>'27', '函館市'=>'-34', ], '福岡県' => [ '福岡市'=>'3312', '北九州市'=>'6398', '糸島市'=>'33.5', ] ); $items = []; foreach($memo as $key => $value) { foreach($value as $sub_key => $sub_value) { $items = $sub_key.":".$sub_value; } } echo $items; /* "世田谷区:100 渋谷区:255 町田市:1731 札幌市:27 函館市:-34 福岡市:3312 北九州市:6398 糸島市:33.5" */
- 投稿日:2020-03-20T23:26:14+09:00
Laravel 検索機能サンプル
searchアクションで検索結果があれば表示するサンプル
routes.phpRoute::get('/person/{id}', 'PersonController@find'); Route::post('/person/{id}', 'PersonController@search');controller.phppublic function find(Request $request){ return view('person.find', ['input' => '', 'id' => $request->id]); } public function search(Request $request){ $input_val = $request->input; $item = Person::find($input_val); return view('person.find', ['input' => $input_val, 'id' => $request->id, 'item' => $item]); }view.blade.php<form action="/person/{{$id}}" method="post"> {{ csrf_field() }} <input type="text" name="input" value="{{$input}}"> <input type="submit" value="find"> </form> @if (isset($item)) <table> <tr> <th>Data</th> </tr> <tr> <td>{{ $item->getData() }}</td> </tr> </table> @endif
- 投稿日:2020-03-20T23:07:30+09:00
PHPのisset()と等価な条件式を書いてisset()への理解を深めたい
問い
$hoge
を変数とする。$hoge
は定義されていて、かつ配列型であるとする。このとき、
isset($hoge['fuga']['piyo'])
と等価な条件式を書け。ここで「2つの条件式が等価である」とは、「条件を満たすどのような
$hoge
に対しても2つの条件式の真偽が一致する」ことを意味することとする。また、条件式を書くにあたっては論理演算子と以下の関数のみを用いることとする。
array_key_exists()
is_array
is_null
答えの例
array_key_exists('fuga', $hoge) && !is_null($hoge['fuga']) && is_array($hoge['fuga']) && array_key_exists('piyo', $hoge['fuga']) && !is_null($hoge['fuga']['piyo'])証明
省略
- 投稿日:2020-03-20T20:37:11+09:00
モデルメソッドの使い方
メソッドを定義してuseして使うだけ
# 使い方(Personモデルでの例) use App\Person; #コントローラでuse $person = Person::all(); #インスタンス取得 $Person->モデルメソッド(); #メソッドを使用viewで表示する例:
Person.php# メソッド定義 public function getData() { return $this->id . ':' . $this->name . '(' . $this->age . ')'; }PersonController.phpuse App\Person; use Illuminate\Http\Request; class PersonController extends Controller { public function index(){ $people = Person::all(); return view('person.index', ['people' => $people]); } }person/index.blade.php<table> @foreach($people as $person) <tr> <!-- ここでメソッド呼び出し --> <td>{{ $person->getData() }}</td> </tr> @endforeach </table>
- 投稿日:2020-03-20T19:56:06+09:00
ユリウス日の算出方法
ユリウス日の算出方法を調べていたら、出典によって数式がマチマチでどれが正しいのか困ってしまったのでとりあえず整理。
また、比較も行ってみたが、各算出方法で結果に差があることと傾向は分かったものの、どれが正しいのか、あるいは何か一つの方法を正しいと断ずることはそもそも出来るのかは不明なまま。ユリウス日の算出方法
wikipedia / ユリウス通日#Julian Day Number (JDN) によると、
換算式は、Fliegel and Van Flandern[13]、Hatcher[14]、Meeus[15]によって考案されている。ただしこれらに整理を施した換算式が使われることも多い[16]。
とのことであり、式にはいくつかの形がある模様。
以下に、wikipediaでの式と、他文献等の式を列挙する。それぞれ式の形がかなり違っているけど、ほんとに等価なんだろうか…。
wikipediaの方法
\begin{aligned} JD = & \left\lfloor 365.25 Y \right\rfloor + \left \lfloor \frac{Y}{400} \right\rfloor - \left\lfloor \frac{Y}{100} \right\rfloor + \left\lfloor 30.59 \left( M-2 \right) \right\rfloor + D + 1721088.5 \\ & + \frac{h}{24} + \frac{m}{1440} + \frac{s}{86400} \\ \\ & \lfloor x \rfloorは床関数 \end{aligned}UTの現在のグレゴリオ暦での年をY、月をM、日をD、時間をh、分をm、秒をsとする。ただし、1月と2月はそれぞれ前年(Yの値を-1する)の13月、14月として代入する(例: 2013年2月5日の場合、Y=2012, M=14, D=5)。
Fliegelらの方法
\begin{aligned} JD(I,J,K) = & K - 32075 + 1461 * (I + 4800 + (J - 14) / 12) / 4 \\ & + 367 * (J - 2 - (J - 14) / 12 * 12) / 12 \\ & - 3 * ((I + 4900 + (J - 14) / 12 ) / 100 ) / 4 \end{aligned}calendar date (I = year; J = month, a number from 1 to 12; K = day of month) to a Julian Date (JD)
COMPUTATION AND MEASUREMENT PROBLEM 11.
In FORTRAN integer arithmetic, multiplication and division are performed left to right in the order of occurrence, and the absolute value of each result is truncated to the next lower integer value after each operation, so that both 2/12 and -2/12 become 0.
乗算と除算は左から右に実行され、そのつど計算結果の絶対値は、その次に小さい整数値に切り下げられる。
wikipedia / Julian day#Converting Gregorian calendar date to Julian Day Number
The algorithm[61] is valid for all (possibly proleptic) Gregorian calendar dates after November 23, −4713. Divisions are integer divisions, fractional parts are ignored.
他と比較しやすいよう表現を変えると、
\begin{aligned} JD = & D - 32075 + \left\lfloor \frac{ 1461 \left( Y + 4800 + \left\lfloor \frac{M - 14}{12} \right\rfloor \right)}{4} \right\rfloor \\ & + \left\lfloor \frac{ 367 \left( M - 2 - 12 \left\lfloor \frac{M - 14}{12} \right\rfloor \right) }{12} \right\rfloor \\ & - \left\lfloor \frac{ 3 \left\lfloor \frac{ Y + 4900 + \left\lfloor \frac{M - 14}{12} \right\rfloor }{100} \right\rfloor }{ 4 } \right\rfloor \end{aligned}Hatcherの方法
\begin{aligned} Y' & = Y + y - ((n + m - 1 - M) / n) \text{INT} \\ M' & = (M - m) \text{MOD } n \\ D' & = D - 1 \\ J & = ((pY' + q) / r) \text{INT} + ((sM' + t) / u) \text{INT} + D' -j \end{aligned}Y, M, D and Y', M', D' are the year, month and day of month
(x) INT is the integral part of x, and x is assumed to be positive; (x) MOD y is the positive remainder on divideing x by y.
(x) INTはxの整数部であり、xは正と想定される。(x) MODはxをyで除算した正の剰余。
グレゴリオ暦からの変換の場合は
y j m n r p q v u s t w 4716 1401+g 3 12 4 1461 - 3 5 153 2 2 g = (((Y' + 184) / 100) \text{INT} \times 3/4) \text{INT} - 38と記載されているため、上記の式に代入すると
\begin{aligned} Y' = & Y + 4716 - \left( \frac{14 - M}{12} \right) \text{INT} \\ M' = & (M - 3) \text{MOD } 12 \\ D' = & D - 1 \\ J = & \left( \frac{1461 Y'}{4} \right) \text{INT} + \left( \frac{153M' + 2}{5} \right) \text{INT} + D' \\ & - \left( 1401 + \left( \frac{Y' + 184}{100} \right) \text{INT} \times \frac{3}{4} \right) \text{INT} - 38 \\ = & \left( 365.25Y' \right) \text{INT} + \left( 30.6M' + 0.4 \right) \text{INT} + D' \\ & - \left( 1401 + \left( \frac{Y' + 184}{100} \right) \text{INT} \times \frac{3}{4} \right) \text{INT} - 38 \end{aligned}Meeusの方法
Meeus, J., Astronomical Algorithms, 1998
\begin{aligned} A & = \text{INT} \left( \frac{Y}{100} \right) \\ B & = 2 - A + \text{INT} \left( \frac{A}{4} \right) \\ JD & = \text{INT} (365.25 (Y + 4716)) + \text{INT} (30.6001(M + 1)) + D + B - 1524.5 \end{aligned}Let Y be the year, M the month number (1 for January, 2 for February, etc., to 12 for December), and D the day of month (with decimals, if any) of the given calendar date.
INT(x) the greatest integer less than or equal to x.
for instance, INT(-7.83) = -8
他と比較しやすいよう表現を変えると、
\begin{aligned} JD & = \left\lfloor 365.25 (Y + 4716) \right\rfloor + \left\lfloor 30.6001(M + 1) \right\rfloor + D + 2 - \left\lfloor \frac{Y}{100} \right\rfloor + \left\lfloor \frac{ \left\lfloor \frac{Y}{100} \right\rfloor }{4} \right\rfloor - 1524.5 \\ & = \left\lfloor 365.25 Y \right\rfloor + \left\lfloor 30.6001(M + 1) \right\rfloor + D - \left\lfloor \frac{Y}{100} \right\rfloor + \left\lfloor \frac{Y}{400} \right\rfloor + 1,720,996.5 \\ & = 365 Y + \left\lfloor \frac{Y}{4} \right\rfloor - \left\lfloor \frac{Y}{100} \right\rfloor + \left\lfloor \frac{Y}{400} \right\rfloor + \left\lfloor 30.6001(M + 1) \right\rfloor + D + 1,720,996.5 \end{aligned}Valladoらの方法
CelesTrak / Revisiting Spacetrack Report #3 - AIAA 2006-6753 - Source code (C++)
Vallado, David A., Paul Crawford, Richard Hujsak, and T.S. Kelso, "Revisiting Spacetrack Report #3," presented at the AIAA/AAS Astrodynamics Specialist Conference, Keystone, CO, 2006 August 21–24.\begin{aligned} jd = & 367.0 * year - \\ & floor((7 * (year + floor((mon + 9) / 12.0))) * 0.25) + \\ & floor(275 * mon / 9.0) + day + 1721013.5 + \\ & ((sec / 60.0 + minute) / 60.0 + hr) / 24.0 \\ \end{aligned}他と比較しやすいよう表現を変えると、
\begin{aligned} JD = & 367 Y - \left\lfloor \frac{7}{4} \left(Y + \left\lfloor \frac{M + 9}{12} \right\rfloor \right) \right\rfloor + \left\lfloor \frac{275 M}{9} \right\rfloor + D + 1721013.5 \\ & + \frac{h}{24} + \frac{m}{1440} + \frac{s}{86400} \end{aligned}Howard D. Curtisの方法
ScienceDirect / Julian Day Number
Howard D. Curtis, in Orbital Mechanics for Engineering Students (Fourth Edition), 2020\begin{aligned} J_0 = & 367 y - \text{INT} \frac{7 y + \text{INT} \frac{m + 9}{12}}{4} + \text{INT} \frac{275 m}{9} + d + 1,721,013.5 \\ & 1901 \le y \le 2099 \\ & 1 \le m \le 12 \\ & 1 \le d \le 31 \end{aligned}INT(x) means retaining only the integer portion of x, without rounding (or, in other words, round toward zero). For example, INT(− 3.9) = −3 and INT(3.9) = 3.
ScienceDirect / Julian Day Number
Howard D. Curtis, in Orbital Mechanics for Engineering Students (Third Edition), 2014\begin{aligned} J_0 = & 367 y - \text{INT} \left\{ \frac{7 \left[ y + \text{INT} \left( \frac{m + 9}{12} \right) \right] }{4} \right\} + \text{INT} \left( \frac{275 m}{9} \right) + d + 1,721,013.5 \\ & 1901 \le y \le 2099 \\ & 1 \le m \le 12 \\ & 1 \le d \le 31 \end{aligned}INT (x) means to retain only the integer portion of x, without rounding (or, in other words, round toward zero), that is, INT (−3.9) = −3 and INT (3.9) = 3
上記のFourth EditionとThird Editionでは、第2項の分子の7がかかっている範囲が異なっている。
boostライブラリの方法
boost/date_time/gregorian_calendar.ipp
//! Convert a ymd_type into a day number /*! The day number is an absolute number of days since the start of count */ template<typename ymd_type_, typename date_int_type_> BOOST_DATE_TIME_INLINE date_int_type_ gregorian_calendar_base<ymd_type_,date_int_type_>::day_number(const ymd_type& ymd) { unsigned short a = static_cast<unsigned short>((14-ymd.month)/12); unsigned short y = static_cast<unsigned short>(ymd.year + 4800 - a); unsigned short m = static_cast<unsigned short>(ymd.month + 12*a - 3); unsigned long d = ymd.day + ((153*m + 2)/5) + 365*y + (y/4) - (y/100) + (y/400) - 32045; return static_cast<date_int_type>(d); } //! Convert a year-month-day into the julian day number /*! Since this implementation uses julian day internally, this is the same as the day_number. */ template<typename ymd_type_, typename date_int_type_> BOOST_DATE_TIME_INLINE date_int_type_ gregorian_calendar_base<ymd_type_,date_int_type_>::julian_day_number(const ymd_type& ymd) { return day_number(ymd); }他と比較しやすいよう表現を変えると、
\begin{aligned} a & = \text{INT} \left( \frac{14 - M}{12} \right) \\ y & = Y + 4800 - a \\ m & = M + 12 a - 3 \\ JD & = \text{INT} \left( D + \frac{153m + 2}{5} + 365 y + \frac{y}{4} - \frac{y}{100} + \frac{y}{400} - 32045 \right) \end{aligned}PHPの方法
PHP > マニュアル > 関数リファレンス > 日付および時刻関連 > カレンダー > カレンダー関数
gregoriantojdgregoriantojd — グレゴリウス日をユリウス積算日に変換する
PHPの関数ではあるが、以下の通り実体はCで実装されている模様。
php-src/ext/calendar/calendar.stub.php
calendar.stub.phfunction gregoriantojd(int $month, int $day, int $year): int {}php-src/ext/calendar/calendar.c
calendar.c/* {{{ proto int gregoriantojd(int month, int day, int year) Converts a gregorian calendar date to julian day count */ PHP_FUNCTION(gregoriantojd) { zend_long year, month, day; if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &month, &day, &year) == FAILURE) { RETURN_THROWS(); } RETURN_LONG(GregorianToSdn(year, month, day)); } /* }}} */gregor.czend_long GregorianToSdn( int inputYear, int inputMonth, int inputDay) { zend_long year; int month; /* check for invalid dates */ if (inputYear == 0 || inputYear < -4714 || inputMonth <= 0 || inputMonth > 12 || inputDay <= 0 || inputDay > 31) { return (0); } /* check for dates before SDN 1 (Nov 25, 4714 B.C.) */ if (inputYear == -4714) { if (inputMonth < 11) { return (0); } if (inputMonth == 11 && inputDay < 25) { return (0); } } /* Make year always a positive number. */ if (inputYear < 0) { year = inputYear + 4801; } else { year = inputYear + 4800; } /* Adjust the start of the year. */ if (inputMonth > 2) { month = inputMonth - 3; } else { month = inputMonth + 9; year--; } return (((year / 100) * DAYS_PER_400_YEARS) / 4 + ((year % 100) * DAYS_PER_4_YEARS) / 4 + (month * DAYS_PER_5_MONTHS + 2) / 5 + inputDay - GREGOR_SDN_OFFSET); }他と比較しやすいよう表現を変えると、
\begin{aligned} Y' & = \left\{ \begin{aligned} Y + 4801 \quad (Y < 0) \\ Y + 4800 \quad (Y \ge 0) \end{aligned} \right. \\ M' & = \left\{ \begin{aligned} & M - 3 & (M > 2) \\ & M + 9, \quad Y' = Y' - 1 & (M \le 2) \end{aligned} \right. \\ JD & = \text{INT} \left( \frac{ \frac{Y'}{100} \times 146097 }{4} + \frac{(Y' \% 100) \times 1461}{4} + \frac{153 M' + 2}{5} + D - 32045 \right) \end{aligned}pyorbitalの方法
pyorbital/pyorbital/__init__.py
__init__.pydef dt2np(utc_time): try: return np.datetime64(utc_time) except ValueError: return utc_time.astype('datetime64[ns]')pyorbital/pyorbital/astronomy.py
astronomy.pydef jdays2000(utc_time): """Get the days since year 2000. """ return _days(dt2np(utc_time) - np.datetime64('2000-01-01T12:00')) def jdays(utc_time): """Get the julian day of *utc_time*. """ return jdays2000(utc_time) + 2451545 def _days(dt): """Get the days (floating point) from *d_t*. """ return dt / np.timedelta64(1, 'D')つまり
JD = UTC(Y,M,D,h,m,s) - UTC(2000, 1, 1, 12, 0, 0) + 2451545国立天文台のWebページの方法
1582年10月15日以後はグレゴリオ暦、それより前はユリウス暦の規則に従った日付となります。
紀元元年の前年を0年としています。このため、これを紀元前1年とする方法とは1年ずつ差異があります。Webフォームに入力することでユリウス日を算出することができる。
他の算出方法での結果と比べるために、CSVファイルに出力しておく。手入力だと大変なため、pythonでWebフォームへリクエストを送信して結果を取得しCSVに出力する。以下は上記のコードで生成したCSVのグラフ。なお、このWebサイトでは -4712/01/01 12:00 が最小値(ユリウス日=0.0日)。
ユリウス暦の最終日である1582/10/04の次の日はグレゴリオ暦の最初日である1582/10/15であるため、Webページもそのような形で結果を返してきている。また、10/05~10/14という値が存在しない形になっている。その影響か、10/24の次が10/15になってしまっている。ともかく、10/04のユリウス日は2299160、10/15のユリウス日は2299161となっており、値が飛ぶことのない線形な結果が維持されている。
各方法の算出結果の比較
横軸:グレゴリオ暦(1582/10/15よりも前をグレゴリオ暦と呼ぶのは不適切な気もする…)
縦軸:ユリウス日なお、NAOJ(国立天文台のWebサイトでの算出結果)については、-4713年~2000年を1ヶ月刻みで算出するのは負荷と時間が心配なので以下の期間だけを算出しており、グラフにも以下の期間でしかプロットされていない。
- -4712年周辺(-4712/01/01 ~ -4711/12/01)
- 0年周辺(0001/01/01 ~ -0001/12/01)
- グレゴリオ暦が始まった1582年10月(1582/10/01 ~ 1582/10/31)
-4713年~2000年
-4713/01/01 ~ 2000/12/01 を1ヶ月刻み(各月の1日)で算出。
俯瞰するとどの算出方法でもほぼ同じ値で、ほぼ線形な結果になっている。
-4713年周辺の拡大図
-4713/01/01 ~ -4711/12/01 を1ヶ月刻み(各月の1日)で算出。
NAOJ(国立天文台のWebサイトでの算出結果)については、このWebサイトでは -4712/01/01 12:00 が最小値(ユリウス日=0.0日)のため、-4712年から始まっている。
0年周辺の拡大図
-0001/01/01 ~ 0001/12/01 を1ヶ月刻み(各月の1日)で算出。
phpのみ、-0001年12月から0000年1月で不連続となっており、phpでは「紀元前1年の次は紀元後1年」という扱いをしていると考えられる。ユリウス日の値から見れば、紀元0年は紀元前1年と同じということになる。
逆にphp以外の方法では、「紀元前1年→紀元0年→紀元後1年」という扱いをしている模様。0年周辺の拡大図、ただし0年は除外して描画
-0001/01/01 ~ -0001/12/01、0001/01/01 ~ 0001/12/01 を1ヶ月刻み(各月の1日)で算出。
前述の通り、ためしに0年を除外してグラフを描画するとphpだけが連続になり、他の方法は不連続になる。
グレゴリオ暦が始まった1582年10月の拡大図
1582/10/01 ~ 1582/10/31 を1日刻みで算出。
NAOJ(国立天文台のWebサイトでの算出結果)については、ユリウス暦の最終日である1582/10/04の次の日はグレゴリオ暦の最初日である1582/10/15になることに従い、10/05~10/14についてはユリウス日の算出対象外になっているため、値が無い。
最大値と最小値の差
-4713/01/01 ~ 2000/12/01 を1ヶ月刻み(各月の1日)で算出。
算出されたユリウス日の値は算出方法間でバラツキがあるため、バラツキがどれくらいかを見るために最大値と最小値の差をプロットしてみた。
- -4713/01/01 ~ -0001/12/01 における差: 417.5 ~ 381.5
- 0000/01/01 ~ 2000/12/01: 17.5 ~ 1.5
- 1582/10/01: 13.5(前述の通り1582/10はNAOJを算出しており、NAOJが最大値を出していて差が大きくなっている)現在に近づくほど差は小さくなってきている。
比較した結論
各算出方法で結果に差があることと傾向は分かったものの、どれが正しいのか、あるいは何か一つの方法を正しいと断ずることはそもそも出来るのかは不明なまま。
ユリウス日における時刻
12:00 UT後のユリウス暦の完全な日付。
\begin{aligned} JD & = JDN + \frac{hour - 12}{24} + \frac{minute}{1440} + \frac{second}{86400} \\ JD & : \text{Julian Date} \\ JDN & : \text{Julian Day Number} \end{aligned}wikipedia / Julian day#Finding Julian date given Julian day number and time of day
その他
Modified Julian Day: MJD(修正ユリウス日)
wikipedia / ユリウス通日#修正ユリウス日(MJD)
wikipedia / Julian day#Variants
Meeus, J., Astronomical Algorithms, 1998\begin{aligned} MJD & = JD - 2400000.5 \\ MJD & : 修正ユリウス日 \\ JD & : ユリウス日 \end{aligned}Truncated Julian Day: TJD
床関数のあるのと無いの、どちらが正しいのか?
TJD = JD - 2440000.5wikipedia / Julian day#Variants
TJD = \left\lfloor JD - 2440000.5 \right\rfloorJ2000
wikipedia / Epoch (astronomy)#Julian Dates and J2000
date that is an interval of x Julian years of 365.25 days away from the epoch J2000 = JD 2451545.0 (TT), still corresponding (in spite of the use of the prefix "J" or word "Julian") to the Gregorian calendar date of January 1, 2000, at 12h TT (about 64 seconds before noon UTC on the same calendar day).10 Like the Besselian epoch, an arbitrary Julian epoch is therefore related to the Julian date by
J = 2000 + ( \text{Julian date} -2451545.0 ) \div 365.25他参考サイト
ユリウス日(Julian Day)
「ユリウス日」で遊ぶ
The Julian Period【Python】 GET・POSTリクエストによるWebデータの取得(Requestsモジュール)
【Python】BeautifulSoupを使ってテーブルをスクレイピング
10分で理解する Beautiful Soup
- 投稿日:2020-03-20T17:12:44+09:00
PHPで階乗を計算する関数
備忘録。PHPで階乗を計算するプログラム。
再帰関数を使わずに実装。
echo factorial_of($num); function factorial_of($num){ $num2 = $num-1; while($num2>0){ $num *= $num2; if($num2>=1){ $num2--; } } return $num; }再帰関数で実装。
echo factorial_of($num); function factorial_of($num){ if($num>0) { return $num *= factorial_of($num-1); } return 1; }
- 投稿日:2020-03-20T16:54:18+09:00
phpListのインストールからテスト送信まで
はじめに
前提として
* PHP、Apache、MySQLはインストール済(データベース作成済)
* PHPに関して、IMAPモジュールがインストールされていること
* メール送信可能なMTAサーバー(Sendmail、Postfixなど、外部サーバーでも可) が必要(ここの設定は今回書いていません)phplistインストール
phpListをインストールしていきます。
zipファイルをダウンロードwget --content-disposition https://sourceforge.net/projects/phplist/files/phplist/3.5.1/phplist-3.5.1.zip/download
/var/www/phplist
に展開(phplistディレクトリは新規に作成)$ unzip phplist-3.5.1.zip -d /var/www/phplistphpListのconfigファイル設定変更
/var/www/phplist/public_html/lists/config/config.php
// 日本語に設定 $default_system_language = 'ja'; // データベースで作成するテーブル名のプレフィックス $usertable_prefix = 'phplist_'; // phplistのルートディレクトリ $pageroot = '/phplist/lists'; // phpListの管理ルートディレクトリを設定 $adminpages = '/phplist/lists/admin'; // データベースの設定 $database_host = 'localhost'; $database_name = 'database_name'; $database_user = 'database_user'; $database_password = 'database_password'; // SMTPサーバーの設定 define('PHPMAILERHOST', 'SMTPサーバー名'); // MTAサーバーへアクセスするユーザ名を設定 $phpmailer_smtpuser = 'smtp_user'; // MTAサーバーへアクセスするユーザのパスワードを設定 $phpmailer_smtppassword = 'password'; // ファイル添付ができるよう設定(0 -> 1) define('ALLOW_ATTACHMENTS', 1); // テストモード解除(1 -> 0) define('TEST', 0);phplist.conf ファイルを新規作成
/etc/httpd/conf.d/phplist.conf
ファイルを新規に作成し、以下を記入する。Alias /phplist /var/www/phplist/public_html <VirtualHost *:80> DocumentRoot /var/www/phplist/public_html ServerName example.com </VirtualHost>Apacheの再起動を忘れずに!
初期画面へ
以下からアクセスできます。
http://example.com/phplist/lists/admin/
- データベースの初期化(設定画面)
以下の4項目を設定して初期化する。エラーがなければOK。
name : organisation : mail_address : password :以降はログイン画面からユーザー名:admin、パスワード:上記で指定したパスワードでログインできます。
phpList側の設定
- サーバーのドメイン名を変更
config > 設定 > generalの設定 > サーバーのドメイン名(メールアドレス用)
- 送信用メールアドレスに変更
config > 設定 > campaignの設定 > キャンペーンの From 行の初期値テスト送信
テストメールを作成
キャンペーン > キャンペーンの送信 > 新しいキャンペーンを開始必要なものの記入が終わったら最下部にある、テスト送信のところに送信先を設定し、
テスト送信
を押下。
※ただし、アドレスが追加されていないものだと送信できず、追加するようアラートが出るので、指示にしたがって追加する。そうすると、無事テスト送信ができる。
ファイル添付について
- lists/config/config.php のALLOW_ATTACHMENTSを追記
- メールにファイル添付がされるのはHTML形式でメッセージを送信したときのみ
- TEXT形式でメッセージを作成すると、ファイルをダウンロードするためのURLがメッセージの末尾に記述される
- メッセージをHTML形式で送信しても、登録されているユーザーの設定が「HTMLメールを受け取る」になっていなければ、TEXT形式でメール送信される
参考:https://blog.songs-inside.com/entry/oss/494
※今回baunceメールの受信設定はしていません。必要であれば、別途設定が必要です。
- 投稿日:2020-03-20T16:05:35+09:00
JavaScriptのthisとPHPのthis
どんな記事?
JavaScriptとPHPのthisを比べながら理解しよう。
背景
thisがよく分からん!
↓
JavaScriptのthis
は他の言語と少々異なる動作をするらしい
↓
よろしい、ならば比較だPHPのthis
PHPの疑似変数である
$this
は、メソッドがオブジェクトコンテキストからコール場合に利用することができる。
$this
は呼び出し元オブジェクトへの参照である。カレントオブジェクトからそのクラス内の関数や変数にアクセスする場合に
$this
を使える。(コンテキストは直訳だと文脈という意味。
プログラミング用語的には、背景となる情報という言い回しが妥当かな?)(カレントオブジェクトとは、インスタンスメソッドが起動されたオブジェクトのこと)
<?php //クラス(Sample) class Sample { //プロパティ($hoge)宣言 public $hoge = 'foo'; //メソッド(display)宣言 public function display() { //displayメソッドで$hogeの内容を呼び出す echo $this->$hoge; } } $sample = new Sample; $sample->display(); //出力結果:foo ?>なぜ
$this
が必要か?それは、
クラス定義の内部では、それにアクセス可能なオブジェクト名を知ることができない
からである。
上記サンプルでは、Sample
クラスが書かれている時点では、
そのオブジェクトの名前があとで$sample
になるのか、はたまた$show
になるのか分からない。その為、
Sample
クラスの中で$sample->$hogeと書くことはできないのである。
代わりに、クラスの中から、そのクラス内の関数や変数にアクセスする為に
$this
を使う。JavaScriptのthis
ほとんどの場合、
this
の値は、関数の呼ばれ方によって決定されます。これは実行時に割り当てできず、関数が呼び出されるたびに異なる可能性があります。ほう。
構文
this値:現在のコードが実行されているJavaScriptコンテキストオブジェクトです
グローバルコンテキスト
JavaScriptにおけるグローバル実行コンテキスト(いずれかの関数の外側)では、
this
はグローバルオブジェクトを参照する。例文//whidowはグローバルオブジェクト //thisはグローバルオブジェクトを示す console.log(this === window); // true //グローバルオブジェクトで宣言 this.hoge = 37; //windowグローバルオブジェクトから //thisで宣言した値を呼び出すことができる console.log(window.hoge); //出力結果:37あれ、PHPとぜんぜん違いますね(驚愕)
関数コンテキスト
単純な呼び出し
次の例は呼び出し時に
this
の値がセットされない為、this
はデフォルトでグローバルオブジェクトとなり、それはブラウザではwindow
と同等である。funcion f1() { return this; } f1() === window; //出力結果:true別のコンテキストから
this
の値を呼び出す場合はcall
もしくはapply
を使用する。//オブジェクト定義 var obj = {a: 'Custom'}; function whatsThis() { return this.a; } whatsThis.call(obj); //出力結果:Customアロー関数
アロー関数では、
this
はそれを囲むレキシカル(静的)なコンテキストのthis
の値が設定される。var globalObject = this; var foo = (() => this); console.log(foo() === globalObject); //出力結果:trueオブジェクトのメソッドとして
関数がオブジェクトのメソッドとして呼び出される時、その
this
にはメソッドが呼び出されたオブジェクトが設定される。次の例では
test.func()
が起動した時、関数内のthis
にはtest
オブジェクトが関連付けられる。const test = { prop: 42, func: function () { retrun this.prop; }, }; console.log(test.func()); //出力結果: 42この振る舞いは、関数定義の方法や場所に全く影響を受けない。
オブジェクトのプロトタイプチェーン上の
this
同じ概念が、オブジェクトのプロトタイプチェーンのどこかに定義されたメソッドにもあてはまる。
そのメソッドがオブジェクト上にあるかのように、this
はメソッドを呼び出したオブジェクトを参照する。var o = { f: function() { return this.a + this.b } } var p = Object.create(o); p.a = 1; p.b = 4; console.log(p.f()); //出力結果:5コンストラクタとして
関数がコンストラクタとして(
new
で生成される)使用される時、そのthis
は生成された新しいオブジェクトにバインド(拘束)される//関数定義 function C() { this.a = 37; } //コンストラクタ生成 var o = new C(); console.log(o.a); //出力結果:37DOMイベントハンドラとして
関数がイベントハンドラとして使用される場合、その
this
にはイベントを発火させた要素が設定される//要素を青色にする関数 function bluify(e) { console.log(this === e.currentTarget); console.log(this === e.target); this.style.backgroundColor = '#A5D9F3'; } //全ての要素を取得 var elements = document.getElementByTagName('*'); //クリックリスナーとしてbluify関数を設定 //クリックした要素が青色に変わる for(var i = 0; i < elements.length; i++){ elements[i].addEventListener('click', bluify, false); }比べてみて
JavaScriptの
this
は、オブジェクトのメソッドやコンストラクトとして使うのであればPHPと同じような理解でいいのかな、と思いました。
DOMイベントハンドラとしてはフロントエンドならでは、という感じですね。グローバルコンテキスト・関数コンテキストでの
this
は、まだ使い道が分からん...参考
PHP: クラスの基礎 - Manual
PHPで擬似変数$thisって何のためにあるのか?
this - JavaScript|MDN
「コンテキスト」という言葉が何を指しているのかよく分からない
レキシカルスコープとクロージャを理解する
- 投稿日:2020-03-20T12:35:50+09:00
PHP(Laravel)でレコードのinsert, update, delete
insert
DB::table('テーブル名')->insert(配列データ);update
DB::table('テーブル名')->where('更新対象を検索')->update(配列データ);$params = [ 'id' => $request->id, 'name' => $request->name, 'email' => $request->email, 'age' => $request->age ];delete
#使い方 DB::table('テーブル名')->where(検索条件)->delete();#削除ルーティング Route::post('/hoge/delete', 'HogeController@delete');HogeController.phppublic function delete(Request $request){ $id = $request->delete_id; $person = DB::table('people')->where('id', $id); $person->delete(); return redirect('/hello'); }
- 投稿日:2020-03-20T12:22:31+09:00
【PHP】SQLクエリの実行
実行環境
PHP 7.4
Postgre 12.2queryメソッド
SQLステートメント(SQLで作成した命令文)を実行し、成功した場合は PDOStatement オブジェクト、失敗した場合はfalseを返します。
$db = new PDO("pgsql:host=localhost; dbname=postgres;","user","password"); $sql = "INSERT INTO test_tbl (id,name) VALUES (1,'yamada')"; $action = $db->query($sql);SELECTした結果を使いたい場合などはqueryメソッドを使用します。
execメソッド
SQLステートメントによって更新や削除された行数を返します。
1行も作用しなかった場合は0を返します。$db = new PDO("pgsql:host=localhost; dbname=postgres;","user","password"); $sql = "INSERT INTO test_tbl (id,name) VALUES (1,'yamada')"; $action = $db->exec($sql); if($action>0) { echo "{$action}件のデータ挿入"; } else { echo "データ挿入失敗"; }行数を返すので、ifやforで活用できますね。
- 投稿日:2020-03-20T04:39:17+09:00
【PHP】連想配列に代入した値を使って文字を置換する
入力した文字列の中から任意の文字を置換したくて、for文使ったりforeach使ってみたりして数時間うんうん悩んでたけど、
strtr()
関数に配列突っ込んだら解決したっていうメモ。なんやそれ?
str_replace — 検索文字列に一致したすべての文字列を置換する
とのこと。
参考: PHP: strtr - Manual引数strtr($検索する文字列, $対象文字列, $置換する文字列);引数に連想配列を渡すこともできる。
$key
が対象文字列、$value
が置換する文字列になる。引数に連想配列を渡す$s = 'AI'; $ary = ['A' => 1]; echo strtr($s, $ary); //実行結果 1I実装
<?php $str = 'PIZZA EAT PIZZA'; $words = [ 'A' => 4, 'E' => 3, 'G' => 6, 'I' => 1, 'O' => 0, 'S' => 5, 'Z' => 2, ]; echo $str."\n"; echo strtr($str, $words); //実行結果 PIZZA EAT PIZZA P1224 34T P1224おわり
str_replace()
ちゅーものもあるみたい。パラメータが多くて便利そうだけど、使うときに注意が必要っぽい。
参考1: PHP: str_replace - Manual
参考2: str_replaceとstrtrの違いって何なのさ
- 投稿日:2020-03-20T02:45:04+09:00
PHP 年と月からその月の長さ(最終日)を取得する うるう年判定込
function checkFinalDay($year,$month){ $finalDay = [ "1" => 31, "2" => 28, "3" => 31, "4" => 30, "5" => 31, "6" => 30, "7" => 31, "8" => 31, "9" => 30, "10" => 31, "11" => 30, "12" => 31, ]; if( $year%4 == 0 && $year%100 != 0 || $year%400 == 0 { $finalDay["2"] = 29; } return $finalDay[$month]; }
- 投稿日:2020-03-20T01:32:50+09:00
SimpleSAMLPHPでIdPのログインページをカスタマイズする方法
やりたいこと
SimpleSAMLPHPを使ってIdpを構築してSSOをやっているのですが
いざ、構築し終わったらデフォルトのログインページのままこれではだめなので変えようとしたところ死ぬほど苦戦したのでメモ
実現方法
デフォルトのログイン画面は
modules/core/templates/loginuserpass.tpl.php
になりますこいつをオーバライドしてやる必要があるわけです。
SimpleSAMLPHPにはテーマ機能があって、すべての画面をカスタマイズできます。
しかしその情報が公式ドキュメントのみなので面倒です公式の通りにディレクトリを作成します
cd modules mkdir mymodule cd mymodule touch default-enable cd modules/mymodule mkdir -p themes/fancythemeconfigの設定を変えます
'theme.use' => 'mymodule:fancytheme',公式の例3を確認すると
たとえば、preprodwarningテンプレートを上書きするには(ファイルはにありますmodules/preprodwarning/templates/warning.php)、新しいファイルを追加する必要があります。
modules/mymodule/themes/fancytheme/preprodwarning/warning.php
モジュールfoomoduleで言うと、bar.phpテンプレートを表示するいくつかのコード要求、SimpleSAMLphpは次のようになります。最初にテーマを確認して、代替品を探してくださいmodules/mymodule/themes/fancytheme/foomodule/bar.php。
見つからない場合、そのモジュールのベーステンプレートを使用します。 modules/foomodule/templates/bar.phpとあるので
loginuserpass
をオーバーライドしたい場合
今回の場合modules/mymodule/themes/fancytheme
にcore
ディレクトリを作成します。(core内のテンプレートのため)
そこにloginuserpass.php
を作成してやれば上書きできます。
- 投稿日:2020-03-20T00:47:42+09:00
Wordpressでカスタマイザーにオプションを追加する一番簡単な方法
カスタマイザーを使うことでロゴやヘッダー画像のアップロード、テーマカラーの設定などWordpressテーマの様々なオプション設定ができるようになる。
カスタマイザーを作成する方法
functios.phpに以下のコードを追記する。
function mytheme_customize_register( $wp_customize ) { // セクション(グループ)を作成 $wp_customize->add_section( 'theme_color' , array( 'title' => __( 'Theme Color', 'text_domain' ), 'priority' => 21, ) ); // データベースに新しい設定項目を登録 $wp_customize->add_setting( 'color_base' , array( 'default' => '#fff', 'transport' => 'refresh', 'sanitize_callback' => 'sanitize_hex_color', ) ); // 管理画面に表示するコントローラ(フォーム)を登録 $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'color_base', array( 'label' => __( 'Base Color', 'text_domain' ), 'section' => 'theme_color', 'settings' => 'color_base', ) ) ); // 画像のアップロードの場合 $wp_customize->add_section( 'theme_image' , array( 'title' => __( 'Image', 'text_domain' ), 'priority' => 20, ) ); $wp_customize->add_setting( 'logo_upload' , array( 'transport' => 'refresh', 'sanitize_callback' => 'text_domain_sanitize_file', ) ); $wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, 'logo', array( 'label' => __( 'Upload a logo', 'text_domain' ), 'section' => 'theme_image', 'settings' => 'logo_upload', ))); } // カラー設定をCSSで表示するための関数、wp_headで呼び出し function header_output() { $color_base = get_theme_mod('color_base', '#fff'); $css = ' /** * custom theme */ body { color: '.$color_base.'; } ' ?> <style type="text/css"> <?php echo $css; ?> </style> <?php } // 画像用サニタイザー、ファイルタイプをチェックする function text_domain_sanitize_file( $file, $setting ) { //allowed file types $mimes = array( 'jpg|jpeg|jpe' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png' ); //check file type from file name $file_ext = wp_check_filetype( $file, $mimes ); //if file has a valid mime type return it, otherwise return default return ( $file_ext['ext'] ? $file : $setting->default ); } // カスタマイザーの登録 add_action( 'customize_register', 'mytheme_customize_register' ); // headに設定したCSSを表示 add_action( 'wp_head' , 'header_output' );カスタマイザーにオプションを登録するには以下の3つの設定を行う必要がある。
- section: オプションのグループを作る
- setting: オプションの設定をデータベースに登録
- control: オプションの表示(フォームやラベルなど)を設定
コードを追記してカスタマイザーを表示すると、画像のように項目が追加される。
カスタマイザーのデータをテンプレートに表示する方法
上記のコードの場合、headで出力するものはアクションの登録で自動的に表示される。
画像はアップロードしたデータをテンプレート側で取得して表示する必要がある。
取得方法は、
get_theme_mod()
で登録した設定名を指定するだけ。<?php if( get_theme_mod('logo_upload') ): ?> <h1><img src="<?php echo get_theme_mod('logo_upload'); ?>" alt="logo"></h1> <?php endif; ?>
- 投稿日:2020-03-20T00:45:54+09:00
PHP 配列に連想配列を入れたものをforeach文で出力する
目的
- 下記の記事で配列に連想配列を入れることをまとめた、その応用として配列の中身をforeach文で出力する方法をまとめる
実施環境
- MacOS上のローカル環境にテスト用スクリプトファイルを作成してVisual Studio Codeのデバッグを用いて結果を確認した。
- 下記にVisual Studio CodeでPHPのデバッグ環境を構築する際の手順をまとめた記事へのリンクを記載する。
- 下記に実施環境の詳細な情報を記載する。
項目 情報 OS macOS Catalina(10.15.3) ハードウェア MacBook Air (11-inch ,2012) プロセッサ 1.7 GHz デュアルコアIntel Core i5 メモリ 8 GB 1600 MHz DDR3 グラフィックス Intel HD Graphics 4000 1536 MB 書き方の例(連想配列のキーを出力しない)
- 下記に配列に連想配列を入れたものを定義し、foreach文で配列の中の要素がある分だけ繰り返す処理を記載する。
- 配列のインデックスが0の連想配列には'num1' => 10, 'num2' => 20, 'num3' => 30を格納する。
- 配列のインデックスが1の連想配列には'num1' => 40, 'num2' => 50, 'num3' => 60を格納する。
配列のインデックスが2の連想配列には'num1' => 70, 'num2' => 80, 'num3' => 90を格納する。
# 配列の中にインデックス0の連想配列を格納する $data = [ [ 'num1' => 10, 'num2' => 20, 'num3' => 30 ] ] # 配列の末尾に連想配列を追加する(インデックス1の追加) array_push($data, [ 'num1' => 40, 'num2' => 50, 'num3' => 60 ]); # 配列の末尾に連想配列を追加する(インデックス2の追加) array_push($data, [ 'num1' => 70, 'num2' => 80, 'num3' => 90 ]); ]; # 配列のインデックス0の内容から順に$datumに格納される。 # $dataの内容は連想配列なので出力時は連想配列のそれと同じく、連想配列名('キー名')で出力できる。 foreach ($data as $datum){ echo $datum['num1']; echo '/'; echo $datum['num2']; echo '/'; echo $datum['num3']; echo '///'; }