質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

解決済

気づけばプロ並みPHP

xo_yo
xo_yo

総合スコア54

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

2回答

0グッド

1クリップ

1519閲覧

投稿2022/01/05 19:22

編集2022/01/17 16:52

php

1<?php 2session_start(); 3session_regenerate_id(true); 4?> 5<!DOCTYPE html> 6<html lang="en"> 7<head> 8 <meta charset="UTF-8"> 9 <title>Document</title> 10</head> 11<body> 12<?php 13require_once('../common/common.php'); 14$post=sanitize($_POST); 15try{ 16$onamae=$post['onamae']; 17$email=$post['email']; 18$postal1=$post['postal1']; 19$postal2=$post['postal2']; 20$address=$post['address']; 21$tel=$post['tel']; 22 23echo $onamae.'様<br/>'; 24echo'ご注文ありがとうございました。<br/>'; 25echo$email.' にメールを送りましたのでご確認ください。<br/>'; 26echo'商品は以下の住所に発送させていただきます。<br/>'; 27echo $postal1.'-'.$postal2.'<br/>'; 28echo $address.'<br/>'; 29echo $tel.'<br/>'; 30 31$honbun=''; 32$honbun.=$onamae."様\n\nこの度はご注文ありがとうございました。\n"; 33$honbun.="\n"; 34$honbun.="ご注文内容\n"; 35$honbun.="----------\n"; 36 37$cart=$_SESSION['cart']; 38$kazu=$_SESSION['kazu']; 39$max=count($kazu); 40 41$dsn='mysql:dbname=shop;host=localhost;charset=utf8'; 42$user='root'; 43$password=''; 44 45$dbh=new PDO($dsn,$user,$password); 46$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 47 48for($i=0;$i<$max;$i++){ 49 50$sql='SELECT name,price FROM mst_product WHERE code=?'; 51$stmt=$dbh->prepare($sql); 52$data=[]; 53$data[]=$cart[$i]; 54$stmt->execute($data); 55 56$rec=$stmt->fetch(PDO::FETCH_ASSOC); 57 58$name=$rec['name']; 59$price=$rec['price']; 60$kakaku[]=$price; 61$suryo=$kazu[$i]; 62$shokei=$price*$suryo; 63 64$honbun.=$name.''; 65$honbun.=$price.'円×'; 66$honbun.=$suryo.'個='; 67$honbun.=$shokei."円\n"; 68} 69 70$sql='LOCK TABLES dat_sales WRITE,dat_sales_product WRITE'; 71$stmt=$dbh->prepare($sql); 72$stmt->execute(); 73 74$sql='INSERT INTO dat_sales(code_member,name,email,postal1,postal2,address,tel) VALUES(?,?,?,?,?,?,?)'; 75$stmt=$dbh->prepare($sql); 76$data=array(); 77$data[]=0; 78$data[]=$onamae; 79$data[]=$email; 80$data[]=$postal1; 81$data[]=$postal2; 82$data[]=$address; 83$data[]=$tel; 84$stmt->execute($data); 85 86 87$sql='SELECT LAST_INSERT_ID()'; 88$stmt=$dbh->prepare($sql); 89$stmt->execute(); 90$rec=$stmt->fetch(PDO::FETCH_ASSOC); 91$lastcode=$rec['LAST_INSERT_ID()']; 92 93for($i=0;$i<$max;$i++){ 94 $sql='INSERT INTO dat_sales_product(code_sales,code_product,price,quantity) VALUES(?,?,?,?)'; 95$stmt=$dbh->prepare($sql); 96$data=array(); 97$data[]=$lastcode; 98$data[]=$cart[$i]; 99$data[]=$kakaku[$i]; 100$data[]=$kazu[$i]; 101$stmt->execute($data); 102 103} 104 105$sql='UNLOCK TABLES'; 106$stmt=$dbh->prepare($sql); 107$stmt->execute(); 108 109$dbh=null; 110 111$honbun.="送料は無料です。\n"; 112$honbun.="-------------"; 113$honbun.="\n"; 114$honbun.="代金は以下の口座にお振り込みください\n"; 115$honbun.="銀行 00000\n"; 116$honbun.="入金確認が取れ次第、発送させていただきます。\n"; 117$honbun.="〜安心野菜ろくまる園〜\n"; 118$honbun.="\n"; 119$honbun.="東京都123-4\n"; 120$honbun.="電話:000-4444-3333\n"; 121$honbun.="メール:info@inini.com\n"; 122 123//echo'<br/>'; 124//echo nl2br($honbun); 125 126 127//↓メールを送信するシステム  p248 お客側のメール 128$title='ご注文ありがとうございます'; 129$header='From:info@inini.com';//送信元 130$honbun=html_entity_decode($honbun,ENT_QUOTES,'UTF-8'); 131mb_language('japanese'); 132mb_internal_encoding('UTF-8');//mb_language('japanese');mb_internal_encodingこの形のまま覚える 133mb_send_mail($email,$title,$honbun,$header); //mb_send_mail(宛先, 件名, メッセージ, ヘッダ):https://techplay.jp/column/550 134 135 136 137//↓メールを送信するシステム  p248 お店側のメール $headerに注目 138$title='お客様からご注文がありました。'; 139$header='From:'.$email; 140$honbun=html_entity_decode($honbun,ENT_QUOTES,'UTF-8'); 141mb_language('japanese'); 142mb_internal_encoding('UTF-8');//mb_language('japanese');mb_internal_encodingこの形のまま覚える 143mb_send_mail('info@inini.com',$title,$honbun,$header); //mb_send_mail(宛先, 件名, メッセージ, ヘッダ):https://techplay.jp/column/550 144 145}catch(PDOException $e){ 146 exit($e->getMessage()); 147 148} 149 150?> 151 152</body> 153</html>

「SQLSTATE[42000]: Syntax error or access violation: 1044」というエラーについて質問です。

sql

1$sql='LOCK TABLES dat_sales WRITE,dat_sales_product WRITE'; 2$stmt=$dbh->prepare($sql); 3$stmt->execute(); 4 5_____________ 6 7$sql='UNLOCK TABLES'; 8$stmt=$dbh->prepare($sql); 9$stmt->execute();

上記のコードを」書く前は正常にデータがDBに入っていたのですが、上記のコードを書いてから実行しようとすると「SQLSTATE[42000]: Syntax error or access violation: 1044」このようなエラーが出ます。

エラーの内容は、「権限を持っていない」ということだとわかりましたが、なぜ上記のコードを書く前は正常に機能したのに、上記のコードを書いた途端にエラーが出るのでしょうか?

また、いろいろ試しましたが効果がありませんでした。解決のヒントをご教授願います。

________________________________________________
試したこと
https://qiita.com/mako0104/items/63784abab061e587d6c5
こちらの記事を参考にしてみましたが、うまくいきませんでした。

上記の記事を参考にしたところ「zsh: no matches found:」ここのようになり、「https://qiita.com/nisaji/items/f9eede2164a74bc08db7」この記事を参考にしましたが、うまくいきませんでした。

他にも同じような質問あり、真似てみたのですが、解決できませんでした。皆様のお力を借りられたら幸いです。ご教授の方をよろしくお願いいたします。



以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

m.ts10806

2022/01/05 21:08

書籍だけをタイトルにされても要件は分かりません。 https://teratail.com/help/question-tips#questionTips3-1 また、書籍に関係した方も回答で「元々内容がよろしくない」と書かれています。(私もそのようにコメントしています) https://teratail.com/questions/376646#reply-509042 書籍を変えるのを強くすすめます。可能ならPHPマニュアルを主動とした学習を。記事だけ真似ても、根本的な理解(基礎)がないと進まないと思います。
xo_yo

2022/01/05 21:18

書籍だけをタイトルにされても要件は分かりません。 ->申し訳ございません。 書籍に関係した方も回答で「元々内容がよろしくない」と書かれています。 ->そのコメントは幾度も目にしたので、あまりよくない書籍なんだなとは理解しているつもりです。そのために、「安全なwebアプリケーションの作り方」という本を購入しました。後々勉強する予定です。 その上で、なぜ上記のような現象になるのかをご教授願うことは可能でしょうか?よろしくお願いいたします。
m.ts10806

2022/01/05 21:21

質問は編集できますのでまずはタイトルなど調整を。 >安全なwebアプリケーションの作り方 PHPに限らない内容だったと思いますので、「PHPを」となるとちょっと違ってくると思います。 もちろん、Webアプリケーションを作っていく上では必要な知識技術となりますので無駄ではなくむしろ有用ですが。
xo_yo

2022/01/05 21:26

編集しました。ご指摘ありがとうございます。 質問した解答になっていないと思いましたので、再度質問させていただきます。 なぜ、上記のような現象になるのかをご教授願うことは可能でしょうか?よろしくお願いいたします。
m.ts10806

2022/01/05 21:43

ちなみに、PHPのバージョンは幾つでしょうか。
m.ts10806

2022/01/05 21:47

LOCK TABLEが実行できないのではと思って 構文チェッカーで試したところ、 https://rakko.tools/tools/36/ エラー: This command is not supported in the prepared statement protocol yet が出たので調べたところ下記のような質問が出てきたのですが、 https://stackoverflow.com/questions/19965025/mysql-cant-lock-tables-when-using-prepared-statements 当方のPHP7.4では再現しませんでした。 本当にrootなら権限の問題はなさそうですし、、、 念のためユーザーの権限も調べてみてください。 MySQLにログインしてコマンド、もしくはphpMyAdminが入っているなら「ユーザアカウント」のタブから確認できます。
xo_yo

2022/01/05 21:48

バージョンは、7.4.21です。
m.ts10806

2022/01/05 21:53

lock tables / unlockのところ prepare→execute ではなくquery に書き換えてみてください。 https://www.php.net/manual/ja/pdo.query.php もしこれでも同じなら先のコメントに書いたように本当に権限がないのではと懸念。 書籍に書いてあった内容なら、権限について言及されてませんか? (何も言及ないのなら書籍としてはかなりの説明不足です)
xo_yo

2022/01/05 21:55

念のためユーザーの権限も調べてみてください。 ->そこは問題なさそうでした。ここま色々して頂いてありがとうございます。もう少し、コメントを待ちつつ自分でも色々と操作してみます。 朝早くから、ありがとうございました。
m.ts10806

2022/01/05 21:57 編集

>そこは問題なさそうでした どこをどのように確認したのか、結果も質問本文に提示してください(客観的に判断できる情報がないと「本当に問題ないか」誰にも判断できない)。
xo_yo

2022/01/05 22:07

$userと$passwordに自分の名前を入れたものと、元から入っているrootと''の二つあり、両方試しました。 「$sql='LOCK TABLES dat_sales WRITE,dat_sales_product WRITE'; $stmt=$dbh->prepare($sql); $stmt->execute()」このコードを入れる前は、しっかりとDBにデータを入れることができていたので、権限に問題はないと考えています。(自分の名前の$userと$passwordを使用しています) しかし、「SQLSTATE[42000]: Syntax error or access violation: 1044」このようなエラーが出てきて、解決できません。
m.ts10806

2022/01/05 22:29

あのですからPHPからの間接的な実行ではなく、DBの設定情報で確認を。PHPはあくまでMySQLを指定の権限で利用してるに過ぎません。指定のユーザーの権限の確認はできません。 ↓ MySQLにログインしてコマンド、もしくはphpMyAdminが入っているなら「ユーザアカウント」のタブから確認できます。
退会済みユーザー

退会済みユーザー

2022/01/06 00:36

「SET autocommit=0;」しないでLOCK TABLES文って使えるんでしょうか?

回答2

3

おはようございます。

以下の検証用コードを用意し、私の環境で実行してみました。
DBユーザーは root です。

PHP

1<?php 2session_start(); 3session_regenerate_id(true); 4?> 5<!DOCTYPE html> 6<html lang="en"> 7<head> 8 <meta charset="UTF-8"> 9 <title>Document</title> 10</head> 11<body> 12<?php 13//require_once('../common/common.php'); 14//$post=sanitize($_POST); 15try{ 16//$onamae=$post['onamae']; 17//$email=$post['email']; 18//$postal1=$post['postal1']; 19//$postal2=$post['postal2']; 20//$address=$post['address']; 21//$tel=$post['tel']; 22 23$onamae = '山田 テスト'; 24$email = 'yamada.test@foo.com'; 25$postal1 = '999'; 26$postal2 = '9999'; 27$address = 'テスト住所'; 28$tel = '09099999999'; 29 30//echo $onamae.'様<br/>'; 31//echo'ご注文ありがとうございました。<br/>'; 32//echo$email.' にメールを送りましたのでご確認ください。<br/>'; 33//echo'商品は以下の住所に発送させていただきます。<br/>'; 34//echo $postal1.'-'.$postal2.'<br/>'; 35//echo $address.'<br/>'; 36//echo $tel.'<br/>'; 37 38$honbun=''; 39$honbun .=$onamae."様\n\nこの度はご注文ありがとうございました。\n"; 40$honbun .="\n"; 41$honbun .="ご注文内容\n"; 42$honbun .="----------\n"; 43 44//$cart=$_SESSION['cart']; 45//$kazu=$_SESSION['kazu']; 46$cart = array(1,2,3); 47$kazu = array(3,4,1); 48 49$max=count($kazu); 50 51$dsn='mysql:dbname=shop;host=localhost;charset=utf8'; 52$user='root'; 53$password='********'; 54 55$dbh=new PDO($dsn,$user,$password); 56$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 57 58echo "checkpoint 01\n"; 59 60for($i=0;$i<$max;$i++){ 61 62$sql='SELECT name,price FROM mst_product WHERE code=?'; 63$stmt=$dbh->prepare($sql); 64$data=[]; 65$data[]=$cart[$i]; 66$stmt->execute($data); 67 68$rec=$stmt->fetch(PDO::FETCH_ASSOC); 69 70$name=$rec['name']; 71$price=$rec['price']; 72$kakaku[]=$price; 73$suryo=$kazu[$i]; 74$shokei=$price*$suryo; 75 76$honbun.=$name.''; 77$honbun.=$price.'円×'; 78$honbun.=$suryo.'個='; 79$honbun.=$shokei."円\n"; 80} 81 82echo "checkpoint 02\n"; 83 84$sql='LOCK TABLES dat_sales WRITE,dat_sales_product WRITE'; 85$stmt=$dbh->prepare($sql); 86$stmt->execute(); 87 88echo "checkpoint 03\n"; 89 90$sql='INSERT INTO dat_sales(code_member,name,email,postal1,postal2,address,tel) VALUES(?,?,?,?,?,?,?)'; 91$stmt=$dbh->prepare($sql); 92$data=array(); 93$data[]=0; 94$data[]=$onamae; 95$data[]=$email; 96$data[]=$postal1; 97$data[]=$postal2; 98$data[]=$address; 99$data[]=$tel; 100$stmt->execute($data); 101 102echo "checkpoint 04\n"; 103 104$sql='SELECT LAST_INSERT_ID()'; 105$stmt=$dbh->prepare($sql); 106$stmt->execute(); 107$rec=$stmt->fetch(PDO::FETCH_ASSOC); 108 109echo "checkpoint 05\n"; 110 111$lastcode=$rec['LAST_INSERT_ID()']; 112 113for($i=0;$i<$max;$i++){ 114 $sql='INSERT INTO dat_sales_product(code_sales,code_product,price,quantity) VALUES(?,?,?,?)'; 115$stmt=$dbh->prepare($sql); 116$data=array(); 117$data[]=$lastcode; 118$data[]=$cart[$i]; 119$data[]=$kakaku[$i]; 120$data[]=$kazu[$i]; 121$stmt->execute($data); 122 123} 124 125echo "checkpoint 06\n"; 126 127$sql='UNLOCK TABLES'; 128$stmt=$dbh->prepare($sql); 129$stmt->execute(); 130 131echo "checkpoint 07\n"; 132 133$dbh=null; 134 135$honbun.="送料は無料です。\n"; 136$honbun.="-------------"; 137$honbun.="\n"; 138$honbun.="代金は以下の口座にお振り込みください\n"; 139$honbun.="楽天銀行 タスク支店 00000\n"; 140$honbun.="入金確認が取れ次第、発送させていただきます。\n"; 141$honbun.="〜安心野菜ろくまる園〜\n"; 142$honbun.="\n"; 143$honbun.="東京都秋葉原123-4\n"; 144$honbun.="電話:080-4444-3333\n"; 145$honbun.="メール:info@inini.com\n"; 146 147//echo'<br/>'; 148echo nl2br($honbun); 149 150 151//↓メールを送信するシステム  p248 お客側のメール 152//$title='ご注文ありがとうございます'; 153//$header='From:info@inini.com';//送信元 154//$honbun=html_entity_decode($honbun,ENT_QUOTES,'UTF-8'); 155//mb_language('japanese'); 156//mb_internal_encoding('UTF-8');//mb_language('japanese');mb_internal_encodingこの形のまま覚える 157//mb_send_mail($email,$title,$honbun,$header); //mb_send_mail(宛先, 件名, メッセージ, ヘッダ):https://techplay.jp/column/550 158 159 160 161//↓メールを送信するシステム  p248 お店側のメール $headerに注目 162//$title='お客様からご注文がありました。'; 163//$header='From:'.$email; 164//$honbun=html_entity_decode($honbun,ENT_QUOTES,'UTF-8'); 165//mb_language('japanese'); 166//mb_internal_encoding('UTF-8');//mb_language('japanese');mb_internal_encodingこの形のまま覚える 167//mb_send_mail('info@inini.com',$title,$honbun,$header); //mb_send_mail(宛先, 件名, メッセージ, ヘッダ):https://techplay.jp/column/550 168 169}catch(PDOException $e){ 170 exit($e->getMessage()); 171 172} 173 174?> 175 176</body> 177</html>

すると以下の結果になりました。

html

1 2<!DOCTYPE html> 3<html lang="en"> 4<head> 5 <meta charset="UTF-8"> 6 <title>Document</title> 7</head> 8<body> 9checkpoint 01 10checkpoint 02 11checkpoint 03 12checkpoint 04 13checkpoint 05 14checkpoint 06 15checkpoint 07 16山田 テスト様<br /> 17<br /> 18この度はご注文ありがとうございました。<br /> 19<br /> 20ご注文内容<br /> 21----------<br /> 22じゃがいも50円×3個=150円<br /> 23なす30円×4個=120円<br /> 24ブロッコリー60円×1個=60円<br /> 25送料は無料です。<br /> 26-------------<br /> 27代金は以下の口座にお振り込みください<br /> 28楽天銀行 タスク支店 00000<br /> 29入金確認が取れ次第、発送させていただきます。<br /> 30〜安心野菜ろくまる園〜<br /> 31<br /> 32東京都秋葉原123-4<br /> 33電話:080-4444-3333<br /> 34メール:info@inini.com<br /> 35 36</body> 37</html> 38

最後まで処理が実行できたことが確認できました。

続いて、DBユーザーを LOCK TABLES 権限のないユーザーに変更して実行したところ、

以下のような実行結果になりました。

html

1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6</head> 7<body> 8checkpoint 01 9checkpoint 02 10SQLSTATE[42000]: Syntax error or access violation: 1044 Access denied for user 'phpmyadmin'@'localhost' to database 'shop'

チェックポイント2と3の間で異常終了していることが伺えます。
おそらくLOCK TABLES権限がないことが理由だと考えられます。
質問者さんは root で動かしているのですよね?
LOCK TABLES 権限の有無を確認していただいてよろしいですか?

投稿2022/01/05 23:06

srsnsts

総合スコア441

yambejp, m.ts10806👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

m.ts10806

2022/01/06 01:26

コメントで >(自分の名前の$userと$passwordを使用しています) というのを仰っていたので提示のコードと実情が異なっているものと思われます。 当該書籍でユーザーロールの細かいところまで言及していればまだ分かりませんが、PHPの説明がメインの場合って大体rootなので、質問者がそのあたりしっかり調査、調整せずに自分のユーザーを作って使ってる可能性はありそうですね。
srsnsts

2022/01/06 07:47

m.ts10806さん コメントありがとうございます。 そうですか、質問者さんが提示されたコードでは root で接続しているように見えたのですが、 実際にはそうではない可能性があるということですね。 そうなるとこちらとしてはどう説明すればよいのか難しいですね。
m.ts10806

2022/01/06 07:52

私はこの回答で十分だと思っています。 「ロック権限ないユーザーだとエラーになるので、ロック権限のあるユーザーを使うor現在のユーザーにロック権限をつけてください」 以外には言いようがありませんし
srsnsts

2022/01/06 08:03

m.ts10806さん 再度のコメントありがとうございます。 評価いただき嬉しく思います。 そうですね、rootであろうと一般ユーザーであろうと、lock tables権限がなければ動作しませんし、 その辺が質問者さんにうまく伝わればいいのですが。
xo_yo

2022/01/06 08:07

権限自体は、前にも同じような状況になった時に「GRANT ALL On db1.* To 〇〇@localhost;」で全ての権限を与えていたので、問題ないと思います。「SHOW GRANTS for 〇〇@localhost;」確認したところ権限は与えられていました。(〇〇は自分の名前です)
xo_yo

2022/01/06 08:08

こちらの都合で返信が遅くなり、申し訳ございません。
srsnsts

2022/01/06 08:11

xo_yoさん コメントありがとうございます。 そうですか、実行したユーザーで権限あるんですね。 もしかしたらテーブルがロックかかりっぱなしになっていて 新たにロック取れなくなっているのかもしれませんね。 まぁ推測に過ぎないのですが。
xo_yo

2022/01/06 08:12

すいません!!解決しました!!色々とありがとうございました!

0

自己解決

GoogleChromeのキャッシュを削除した所、何故か上手く行きました。権限には、何も問題がなかったようです。

投稿2022/01/06 08:11

xo_yo

総合スコア54

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

srsnsts

2022/01/06 08:14

解決してよかったです。
xo_yo

2022/01/06 08:14

すいません!ありがとうございました!!

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。