ラベル PHP の投稿を表示しています。 すべての投稿を表示
ラベル PHP の投稿を表示しています。 すべての投稿を表示

月曜日, 7月 28, 2025

PHP: 定数を扱う

プロジェクトごとの定数を扱うクラス Config\Constants の紹介です。



<?php

namespace Config;

class Constants
{
    public const DB_USER = "linguist";



呼び出す場合はcomposer を使って use でクラスを読み込みます。


use Config\Constants;

$loader = new \Twig\Loader\FilesystemLoader(Constants::TEMPLATE_DIR);


定数クラスは静的であるため、どこからでも呼び出し可能です。

composer.json で読み込みを指定します。


    "autoload": {
        "psr-4": {
            "Config\\": "src/Config/",
            ...


 git には載せたくない場合でも .gitignore で指定すれば除外できます。


水曜日, 7月 23, 2025

PHP: Composer の使い方

PHP には Composer という優れたパッケージ管理ツールがあります。最近、PHP サイトを Composer を使って再構築する作業を行いましたので、方法を書いておきたいと思います。

Composerとは?

ComposerはPHPのパッケージ管理ツールです。PythonにおけるPoetryに似ており、依存関係の管理とプロジェクトの構造化を支援してくれます。

  • composer.json によってすべての依存情報を一元管理

  • Packagistというリポジトリから多くのパッケージをインストール可能

  • Composerの最大の魅力のひとつが、オートローディング機能です。PSR-4準拠の設定を行えば、名前空間に応じてクラスファイルが自動的に読み込まれます。


インストール方法はこちら⇒公式サイト


プロジェクトの初期化

プロジェクトフォルダで以下のコマンドを実行して composer.json を生成します:

composer init

オートローディング設定

composer.json に以下を追加してクラスを読み込みます。

"autoload": {
        "psr-4": {
            "Pages\\": "src/Pages/"
        }
    }

追加後は以下のコマンドを実行して、オートロード情報を更新します。

composer dump-autoload

使用法

EditPage というクラスを作るなら、src/Pages/EditPage.php ファイルで namespace を指定し、クラスを定義します。

namespace Pages;

class EditPage {
    public static function hello() {
        return "EditPage::hello() が呼ばれました。";
    }
}

EditPage を使うファイルで以下を設定します。

require 'vendor/autoload.php';

use Pages\EditPage;

echo EditPage::hello();

水曜日, 7月 02, 2025

Laravel サイトのアップグレード

 Laravel のサイトをアップグレードする機会がありましたので、その方法をここで書いておきたいと思います。かなり構成というか書き方が変わってきているので注意が必要です。

1. 新しいLaravelプロジェクトの作成

まずはクリーンなLaravel環境を作成します。

composer create-project laravel/laravel new-site

2. 既存コードの移行

必要なファイルを新しいプロジェクトにコピーします:

  • コントローラapp/Http/Controllers

  • モデルapp/Models

  • ビューresources/views

  • ルーティングroutes/web.php または routes/api.php

  • ミドルウェア、サービス、ジョブなど → 必要に応じて

3. Composerのオートロードを更新

クラスのオートロードを再生成します。

composer dump-autoload

4. 必要なパッケージの再インストール

Spatieの権限管理パッケージを使っている場合なら

composer require spatie/laravel-permission

5. Apacheの設定に注意

重要なのが、Apacheの mod_rewrite モジュールを有効化することです。これはひっかかりました。これを忘れるとルーティングが正しく機能せず、トップページしか表示できません。

LoadModule rewrite_module modules/mod_rewrite.so

6. ルーティングの見直し・更新

Laravelのバージョンアップに伴い、ルーティングの記述方法や構文が変更されていることがあります

  • クロージャベースのルートやコントローラルートにおける名前空間の指定方法

  • Route::controller()Route::middleware() を使用したグルーピング構文

  • Web/APIルートファイルでのミドルウェアやプレフィックスの指定

Laravel 8以降では、RouteServiceProvider が変更されましたので変更が必要な場合があります。web.php の記述はこれで動きます。

use App\Http\Controllers\CaseController;

Route::resource('case', CaseController::class);

火曜日, 12月 26, 2017

互換性(mysql_xxx)

年末の大掃除ですね。古いコードを再利用しようとしたらひっかかりました。PHP って互換性ないんですね。

mysql_xxx この辺を全部 mysqli クラスの関数へ変換。変数の順序が違う。

迷惑ですね。

しかしながら思うんですが…

プログラミング言語ってのはプロトコルですよ。一方的な変更は勝手ですよね。

少なくとも互換性は確保してほしい。


火曜日, 8月 22, 2017

Laravel 5.4 のすすめ (データベース篇)

Laravel でデータベースのテーブルを作る作業は ORM まできちんと定式化されています。

まずはテンプレートを使って migration のファイルを自動生成し、テーブルを記述。ファイルはここ database/migrations/* 。

php artisan make:migration create_テーブル名 --create=テーブル名

テーブルの記述はこのような形式です。

$table->string('en');
$table->string('ja');
$table->integer('order_id');        

コマンドを使用してテーブルを作成します。データベース設定ファイルは .env です。

php artisan migrate

あとはモデルを自動生成。これでマッピングが完了。

php artisan make:model テーブル名

 $table 変数でテーブル名を指定できます。

class Office extends Model
{
    protected $table = 'office';
}

専用のページを作りたければ、コントローラーを作ってビューを生成します。個々のレコードのページを作っておくと、編集ができますね。その際は routes/web.php の編集が必要です。

php artisan make:controller コントローラー名 --resource

ロールバックでテーブルを消去したり、シードを使ってデータを放り込むこともできます。

日曜日, 8月 20, 2017

(仕様が変更された)Laravel 5.4 を使う

故あって Laravel で PHP サイトを作ることとなりました。ので概要をメモっておきたいと思います。

これ MVC とか ORM とか DI とか軽く使えるよくできてるシステムなんですが、いまだマイナー系なのかなんなのか仕様がバージョンごとコロコロ変わる。

ついこのあいだ ver. 5.1 で書いて ver. 5.4 で動かそうと思うと… 動きます。ライブラリをそのままコピーしてあるからなんですが、これが新たなプロジェクトをたちあげようとするとライブラリの仕様が変更されている。

新しいライブラリはメソッドなど整理されていて使いやすくなっていますが、仕様が異なるので同じ調子で書いていくとエラーが続出します。

まずは新しいプロジェクトの作り方から。

laravel new プロジェクト名

これでライブラリなどすべてコピーされて完全なシステムが出来上がります。それはいいんですが、ここでまずルーティングのファイルの置き場所が違う。ファイル名まで違う。ver. 5.3 で変更されたようです。

ROUTING:
routes/web.php

ここですね。あとビューとかコントローラーとかは同じです。

VIEW:
resources/views/*.blade.php

CONTROLLER:
app/Http/Controllers/*.php

ルーティングの書き方はこんな感じです。

Route::resource('/dashboard','OrderController');

これですべてページからのリクエストが仕分けされてコントローラーで処理できます。これはいいですね。

動詞 URI アクション ルート名
GET /photos index photos.index
GET /photos/create create photos.create
POST /photos store photos.store
GET /photos/{photo} show photos.show
GET /photos/{photo}/edit edit photos.edit
PUT/PATCH /photos/{photo} update photos.update
DELETE /photos/{photo} destroy photos.destroy

これどういうことかってページから投げられるリクエストでそれぞれアクションを呼べるわけなんです。DELETE って投げれば destroy ってメソッドを定義するだけできちんと動くサイトが出来てしまうわけです。

こうやってビューでフォームを指定します。DELETE を投げてるわけですね。

<form method="post" action="/dashboard/{{$task->id}}">
{{ csrf_field() }} 
{{ method_field('delete') }} 
<input type='submit' value='Remove' 
class='btn btn-danger btn-sm' />
</form>

で、コントローラーを定義します。

    public function destroy($id)
    {
        $order= Order::findOrFail($id);
        $order->delete();
        return redirect ( '/dashboard' );
    }

これだけでリクエストが仕分けされて処理できるって仕組みです。うまいですね。

Order ってのはデータベースのテーブルがマップされたオブジェクトです。ORM ってのは便利ですね。delete() って呼ぶだけで作業は完了です。

Laravel ってのは頭が整理されるとってもよいフレームワークだと思います。しかしながら仕様変更が激しいので要注意です。

火曜日, 5月 13, 2014

Javascript (jQuery) から PHP の関数を呼び出す

ボタンを押したときに、PHP の関数を呼び出したいとします。

Form を使って PHP ファイルを読み込み、ページ全体を書き直すという手段もありますが、ある関数だけを呼び出したいときなど、ajax を使うと PHP 関数を呼び出してページ側で返り値を得ることができます。

このように、url でファイル名を指定して、success で返り値 results として引き渡してやります。

PHP ファイル側では、渡したい値を echo などで表示します。

これで PHP の関数をページから呼び出すことができます。


火曜日, 2月 25, 2014

MySQL: テーブル構造を取得し、SQL文に変換する

MySQLでテーブル構造を取得するには、DESCRIBE (テーブル名) などのSQL文を使用します。



これをSQL文に変換するには、テーブルの情報をSQL文の形式でそれぞれ記述してやる必要があります。

CREATE TABLE IF NOT EXISTS `notes` (
  `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` text COLLATE utf8_unicode_ci NOT NULL,
  `description` text COLLATE utf8_unicode_ci NOT NULL,
  `videoid` text COLLATE utf8_unicode_ci NOT NULL,
  `imagefile` text COLLATE utf8_unicode_ci NOT NULL,
  `docnum` text COLLATE utf8_unicode_ci NOT NULL,
  `shortdesc` text COLLATE utf8_unicode_ci NOT NULL,
  `onhold` int(11) NOT NULL,
  `registered` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 
AUTO_INCREMENT=61 ;

ここで気をつけねばならないのは、timestamp値をとるコラムです。

デフォルト値に CURRENT_TIMESTAMP をとるコラムは、TIMESTAMP 値をとるコラムより前に記述しなければなりません。

コラムを並べ替える必要があります。

ここでは array_unshift() という関数を使用し、CURRENT_TIMESTAMP をとるコラムを配列の最初に格納するという方法をとりました。

ソースコード: GitHub: tablestructure.php

木曜日, 12月 19, 2013

PHP: HTML セーフなコードに変換

HTMLコードを書く際に、不等号記号などそのまま書くとブラウザが勝手に変換してしまいます。

プログラムなどを表示するためには、記号をHTMLに変換しなければなりません。

ブラウザの勝手な行動を制限するために、変換するツールを作成しました。

使い捨てないツールのためにここにアップします。

以下のコードを html.php というファイルに保存し、PHP の動く環境でブラウザを使って表示します。

テキストボックスにコードを打ち込み、Convert ボタンを押すと変換されたコードが表示されます。

<html>
<head>
<style>
textarea
{
width:1000px;
height:500px;
}
</style>
</head>
<body>

<?
$text=$_REQUEST['text'];

$text=htmlspecialchars($text);

echo <<<END
<form action="html.php">
<textarea name="text">$text</textarea>
<input type="submit" value="Convert" />
</form>
END;

$html=htmlspecialchars($text);
echo <<<END
<textarea>
$html
</textarea>
END;
?>
</body>
</html>

日曜日, 11月 24, 2013

PHP: CSVをHTML形式のテーブルに変換

CSV を HTML 形式のテーブルに変換するニーズというのは多々あるものです。

HTML のテーブル形式に変換したいときに使えるツールを作ってみました。

CSV 形式のデータを上のテキストボックスにほうりこみ、Convert ボタンをクリックすると変換された HTML コードが表示されます。

ツールを使い捨てないためにここにアップします。

<html>
<head>
<style>
textarea
{
width:1000px;
height:500px;
}
</style>
</head>
<body>

<?
$text=$_REQUEST['text'];

echo <<<END
<form action="table.php">
<textarea name="text">$text</textarea>
<input type="submit" value="Convert" />
</form>
END;

$text=$_REQUEST['text'];
$text=htmlspecialchars($text);
$list=explode("\n",$text);
$html="";
foreach($list as $line)
  {
    $columnList=explode(",",$line);
    $column=implode("</td><td>",$columnList);
    $html.="<tr><td>$column</td></tr>";
  }
$html="<table><tbody><pre>
$html
</pre></tbody></table>
";
echo <<<END
<textarea>
$html
</textarea>
$html
END;
?>
</body>
</html>

火曜日, 8月 28, 2012

xampp 1.8 にアップグレードしました。

xamppをアップグレードしました。Ver. 1.8が最新のようです。

MySQLもアップグレードとなるので、データベースも移動することになります。

このあたりは、data以下をすべてまるごとコピーでOK。

phpMyAdminでID/Passwordの設定を行ってデータベースがきちんと移動できたかどうかを確認して一安心。

ファイル: config.inc.php
$cfg['Servers'][$i]['user'] = 'ユーザー名';
$cfg['Servers'][$i]['password'] = 'パスワード';

PHPのデフォルトがすべての警告を表示するとなっているので、まずそいつに黙ってもらって無事にアップグレードを完了。

ファイル: /php/php.ini
;error_reporting = E_ALL | E_STRICT
error_reporting = E_ERROR

を使えるようにして、curlを有効にする。

short_open_tag = On

extension=php_curl.dll
 
コントロールパネルもアップグレードされておりました。

月曜日, 2月 13, 2012

"Overload"? or hooking get/set in PHP

In PHP, there are a set of functions that hooks getting and setting private member variables.  When the variable is set, __set() method will be called.  When the variable is accessed, __get() method is called.  In PHP's terminology, hooking variable definition and retrieval are called overloading. 

class HookTest
{
private $a=1;

public function __get($name)
{
  echo "$name is being retrieved<br />";
  return $this->$name;
}

public function __set($name,$value)
{
  echo "$name is being set<br />";
  $this->$name=3;
}
}

echo "<pre>";

$test=new HookTest;
$test->a=2;
echo $test->a;

土曜日, 11月 28, 2009

PHPで、棒グラフ

PHPで、棒グラフなど書くことができます。画像に書き出してそれをHTMLのページに埋め込むことができるということです。データベースからデータを読み出して、グラフにして表示することが、オンラインで可能です。

以下のコードを、.php ファイルに保存して、ApacheなどPHPの動く環境でブラウザでアクセスすると、t.png の画像ファイルができて棒グラフになっているはずです。




$data=array();

array_push($data,1);
array_push($data,2);
array_push($data,3);

$width=300;
$height=10+10*count($data);

$image=imagecreatetruecolor($width,$height);

$white=imagecolorallocate($image,255,255,255);
imagefilledrectangle($image,0,0,$width,$height,$white);
$black=imagecolorallocate($image,0,0,0);
$i=0;
foreach($data as $item)
{
$y0=5+10*$i;
$x1=$item*10;
imagefilledrectangle($image,0,$y0,$x1,$y0+10,$black);
$i++;
}

$filename="t.png";
imagepng($image,$filename);
imagedestroy($image);

?>



日曜日, 10月 11, 2009

PHP: ディレクトリを丸ごとコピーします。

ディレクトリを丸ごとコピーします。

readdir の返り値はファイル名なので、フルパスではありません。

is_dir の引数には、もとのディレクトリとフルパスを指定します。

ファイルの存在は file_exists で検査します。

To copy a directory recursively in PHP:



function copyDirectory($imageDir, $destDir)
{
$handle=opendir($imageDir);
while($filename=readdir($handle))
{
if(strcmp($filename,".")!=0
&& strcmp($filename,"..")!=0)
{
if(is_dir("$imageDir/$filename"))
{
if(!empty($filename) && !file_exists("$destDir/$filename"))
mkdir("$destDir/$filename");
copyDirectory("$imageDir/$filename","$destDir/$filename");
}
else
{
if(file_exists("$destDir/$filename"))
unlink("$destDir/$filename");
copy("$imageDir/$filename","$destDir/$filename");
}
}
}
}

水曜日, 2月 25, 2009

PHP: PDOやmysqliクラスのない環境

サーバーによって、PHPの環境が違うことがあります。

特に、データベース周りでいくつものパッケージがあるため、PHPのバージョンによって書き方が変わってきます。

PDOを使っていたのに、サーバーで使えない環境だった場合。

mysqliクラスを使っていたのにサーバーでクラスが発見できない場合。

せっかくあるコードが使えないということは、コードのリユースの面から不効率です。

対策としては、mysql*関数で書き直すか、あとは自前でクラスを作る。

そんなときのために、PHPでのクラスの書き方をアップしておきます。



if(!class_exists("mysqli"))
{
class mysqli
{
public $dbname;

function __construct($host,$dbuser,$dbpassword,$dbname)
{
$this->dbname=$dbname;
echo $dbuser;
if(!mysql_connect($host,$dbuser,$dbpassword))
echo "No DB connection established";
}
function query($sql)
{
if(!mysql_select_db($this->dbname))
echo "Database not selected";
return new mysqli_result(mysql_query($sql));
}
};

class mysqli_result
{
public $records;
function __construct($results)
{
$this->records=$results;
}
function fetch_assoc()
{
return mysql_fetch_assoc($this->records);
}
};



作り方としては、mysqliクラス、PDOクラスなど、クラスを作ってメソッドを実装する形となります。

クラス間でやりとりがある場合など、クラスを作って実装します。

ソースを変えずにポータブルなコードが可能になります。

日曜日, 2月 15, 2009

PHP: Resizing image files

The way to resize image files in PHP is straight foward yet not as simple as it should be. Nevertheless, the PHP image library is equipped with image manipulation functions. Here is a function that does the job -- resizing factor should be edited to suit your needs.



function resizePhoto($fileName,$dest)
{
header('Content-type: image/jpeg');

list($width, $height) = getimagesize($fileName);
$ratio=((float)$height)/$width;
$newWidth=90;
$newHeight=(int)($newWidth*$ratio);

$thumb = imagecreatetruecolor($newWidth, $newHeight);
$source = imagecreatefromjpeg($fileName);

imagecopyresized($thumb, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

imagejpeg($thumb,$dest);
}

土曜日, 2月 14, 2009

Xampp on Vista

Xampp mysql won't start on Vista. Moreover, the admin app emits warnings relentlessly looking for a dll. The MySQL installation must be done separately, works fine with MySQL 5.1.

The Japanese messages appear on xampp control panel and administrator page seems to have mixed interpretation of the word "stop" and "stopped".

Calling the PDO class method query() crashes Apache -- stops the service. Apache 2.2, PHP 5.2.8, MySQL 5.1 (separate installation).

火曜日, 11月 25, 2008

PHP: Encrypting the Passwords

Nowadays, you need passwords everywhere, to access to blog admin page, to view member-only BBS, to read articles only available to the selected few, etc. All those sites require passwords. The passwords should be secured at a safe place and they should be safely protected -- encrypted. In PHP, crypt function does the work. It encrypts in a pattern that can be set by another secret keyword.

 
crypt($password,"ea")


Here the secret seed of this encryption is "ea" (happens to be my initials). This is a one way ticket to the password protected world -- there is no way to reverse the encryption unless you decipher the mechanism of PHP's encryption. In the real world checking of passwords, simply compare the resulting mysterious bunch of digits and letters with with the passwords that you would like to check -- with the encrypted ones, with the same secret seed.


strcmp(crypt($entered_password,"ea"),$password_stored_somewhere)==0


Notice that the string comparison is done with strcmp -- it is PHP's ancient trap. Never compare strings with == operator. PHP's inherent conversion machine might convert the string to some integer (or to any type) before doing the comparison.

金曜日, 10月 17, 2008

PHPの配列

PHPでは、配列をハッシュのように使えます。便利です。値を変数に置くと、読みやすいコードを書くことができます。


$springEquinoxDay=(int)(20.8431 + 0.242194 * ( $year - 1980))
- (int)((double)($year - 1980)/4) ;
$springEquinox=array(3,$springEquinoxDay,"春分の日");

$automnEquinoxDay=(int)(23.2488 + 0.242194 * ( $year - 1980))
- (int)(($year - 1980)/ 4);
$automnEquinox=array(9,$automnEquinoxDay,"秋分の日");

$official_holidays=array( array(1,1,"元旦"),
array(2,11,"建国記念日"),
$springEquinox,
array(4,29,"昭和の日"),
array(5,3,"憲法記念日"),
array(5,4,"みどりの日"),
array(5,5,"こどもの日"),
$automnEquinox,
array(11,3,"文化の日"),
array(11,23,"勤労感謝の日"),
array(12,23,"天皇誕生日"));



春分の日・秋分の日の算出方法は、こちらを参照させていただきました。

水曜日, 10月 15, 2008

PHPでのログイン管理

PHPでのログイン管理において、クッキーを使ってセッション番号によって判別する方法を示します。

session_start();
$sessionid=session_id();

if(strcmp($_SESSION['sid'],$sessionid)!=0)
{
$user=$_REQUEST['user'];
$password=$_REQUEST['password'];

if(strcmp($user,$user_cfg)!=0)
{
header('Location: index.php?message=noUser');
}

if(strcmp($password,$password_cfg)!=0)
{
header('Location: index.php?message=noPassword');
}
if(strcmp($user,$user_cfg)==0 && strcmp($password,$password_cfg)==0)
$_SESSION['sid']=$sessionid;
}

セッション番号を記録し、現在のセッション番号と比較するのに、ここではセッション変数を用いています。

セッション変数$_SESSION['sid']に記録されたセッション番号と、session_id()で得られる現在のセッション番号を比較します。もし一致しなければ、ログイン情報をチェックし、一致しなければログイン画面index.phpに移行します。一致すればセッション変数に現在のセッション番号を記録します。

Flask の Blueprint のテンプレート問題

  Flask の Blueprint は、ルート、静的ファイル、テンプレートをまとめて管理できます。しかし、テンプレートが指定できません。 ここでは、Blueprint の template_folder の問題点と回避策を説明します。 Blueprint のテンプレート問題...