클래스 DB_Sql {
var $Debug = 거짓;
var $Home = "/u01/app/Oracle/PRoduct/8.0.4";
var $Remote = 1;
/* 이 쿼리는 첫 번째 연결 직후에 전송됩니다
예:
var $ConnectQuery="ALTER 세션 SET nls_date_언어=독일어 nls_date_format='DD.MM.RRRR'";
-> 이 세션의 날짜 형식을 설정하세요. ora 역할을 수행할 때는 괜찮습니다.
변경할 수 없습니다 */
var $ConnectQuery='';
/* Oracle 8.0.5, Apache 및 php3.0.6의 이상한 오류로 인해
내 시스템 Apache
에서는 ENV를 설정할 필요가 없습니다. FALSE로 설정하지 않으면 좀비로 변합니다!
대신 아파치를 시작하기 전에 이러한 ENV-var를 설정했습니다.
확실하지 않은 경우 시도해 보고 효과가 있으면 시도해 보세요. */
var $OraPutEnv = true;
var $Database = "";
var $User = "";
var $PassWord = "";
var $Link_ID = 0;
var $Query_ID = 0;
var $Record = 배열();
var $행;
var $Errno = 0;
var $Error = "";
var $ora_no_next_fetch=false;
/* 완전성을 위해 db_MySQL에서 복사됨 */
/* 공개: 식별 상수. 절대 바꾸지 마세요. */
var $type = "오라클";
var $revision = "개정: 1.3";
var $Halt_On_Error = "예"; ## "yes"(메시지와 함께 중지), "no"(조용히 오류 무시), "report"(오류는 무시하지만 경고 표시)
/* 공개: 생성자 */
함수 DB_Sql($query = "") {
$this->query($query);
}
/* 공개: 일부 사소한 보고 */
함수 link_id() {
$this->Link_ID를 반환합니다.
}
함수 query_id() {
$this->Query_ID를 반환합니다.
}
함수 연결() {
## 우리가 이 일을 하는 이유를 위에서 확인하세요
if ($this->OraPutEnv) {
PutEnv("ORACLE_SID=$this->데이터베이스");
PutEnv("ORACLE_HOME=$this->홈");
}
if ( 0 == $this->Link_ID ) {
if($this->Debug) {
printf("$this->데이터베이스에 연결() 중...
n");
}
if($this->Remote) {
if($this->Debug) {
printf("
connect() $this->User/******@$this->데이터베이스
n");
}
$this->Link_ID=ora_plogon
("$this->사용자/$this->비밀번호@$this->데이터베이스","");
/**************** (SSilk의 댓글)
내 시스템에서는 작동하지 않습니다.
$this->Link_ID=ora_plogon
("$this->User@$this->Database.world","$this->비밀번호");
***************/
} 다른 {
if($this->Debug) {
printf("
connect() $this->사용자, $this->비밀번호
n");
}
$this->Link_ID=ora_plogon("$this->사용자","$this->비밀번호");
/* (SSilk의 댓글: 이것이 어떻게 작동할지는 모르겠지만 이 내용은 그대로 둡니다!) */
}
if($this->Debug) {
printf("
connect() 링크_ID: $this->링크_ID
n");
}
if (!$this->Link_ID) {
$this->halt("connect() 링크 ID == false " .
"($this->Link_ID), ora_plogon이 실패했습니다.");
} 다른 {
//echo "커밋 on
";
以上就介绍了php 의 oracle 资料库函式库 , 包括了 方库 内容 , 希望对PHP教程有兴趣 的 朋友有所帮助 .
ora_commiton($this->Link_ID);
}
if($this->Debug) {
printf("
connect() Link_ID를 얻었습니다: $this->Link_ID
n");
}
## 연결 쿼리 실행
if ($this->ConnectQuery) {
$this->query($this->ConnectQuery);
}
}
}
## 시스템/사용자당 커서 수를 늘리려면
을 편집하세요.
## init.ora 파일을 초기화하고 max_open_cursors 매개변수를 늘립니다. 당신의 시간은
입니다
## 기본값은 사용자당 100입니다.
## 우리는 query()의 동작을 시도하는 방식으로 변경하려고 했습니다.
## 커서를 안전하게 보호하려면 주의하세요.
## 이전 결과를 사용하지 마세요.
##
## ->disconnect()를 광범위하게 사용할 수도 있습니다!
## 사용되지 않은 QueryID는 때때로 재활용됩니다.
함수 쿼리($Query_String)
{
/* 빈 쿼리를 사용하지 마세요. */
if (비어 있음($Query_String))
{
0을 반환합니다.
}
$this->connect();
$this->lastQuery=$Query_String;
if (!$this->Query_ID) {
$this->Query_ID= ora_open($this->Link_ID);
}
if($this->Debug) {
printf("디버그: 쿼리 = %s
n", $Query_String);
printf("
디버그: Query_ID: %d
n", $this->Query_ID);
}
if(!@ora_parse($this->Query_ID,$Query_String)) {
$this->Errno=ora_errorcode($this->Query_ID);
$this->Error=ora_error($this->Query_ID);
$this->halt("
ora_parse() 실패:
$Query_String
이것을 스냅하여 sqlplus에 붙여넣으세요!");
} elseif (!@ora_exec($this->Query_ID)) {
$this->Errno=ora_errorcode($this->Query_ID);
$this->Error=ora_error($this->Query_ID);
$this->halt("
n$Query_Stringn
이것을 찍어서 sqlplus에 붙여넣으세요!");
}
$this->행=0;
if(!$this->Query_ID) {
$this->halt("잘못된 SQL: ".$Query_String);
}
$this->Query_ID를 반환합니다.
}
함수 next_record() {
if (!$this->ora_no_next_fetch &&
0 == ora_fetch($this->Query_ID)) {
if ($this->Debug) {
printf("
next_record(): ID: %d 행: %d
n",
$this->Query_ID,$this->Row+1);
// $this->Row+1에 대한 자세한 정보는 $this->num_rows()입니다.
// 그러나 모든 경우에 작동하지는 않습니다(복잡한 선택)
// 여기서는 매우 느립니다
}
$this->행 +=1;
$errno=ora_errorcode($this->Query_ID);
if(1403 == $errno) { # 1043은 더 이상 레코드를 찾을 수 없음을 의미합니다.
$this->Errno=0;
$this->오류="";
$this->disconnect();
$stat=0;
} 다른 {
$this->Error=ora_error($this->Query_ID);
$this->Errno=$errno;
if($this->Debug) {
printf("
%d 오류: %s",
$this->Errno,
$this->오류);
}
$stat=0;
}
} 다른 {
$this->ora_no_next_fetch=false;
for($ix=0;$ix
$col=strtolower(ora_columnname($this->Query_ID,$ix));
$value=ora_getcolumn($this->Query_ID,$ix);
$this->기록[ "$col" ] = $value;
$this->기록[ $ix ] = $value;
#DBG echo"[$col]: $value
n";
}
$stat=1;
}
$stat를 반환합니다.
}
##eek()은 $pos - 1 및 $pos에서만 작동합니다
## 아마도 직접 구현을 할 수도 있지만
## 이 작업은 PHP3에서 수행해야 한다는 의견이 있습니다
함수 탐색($pos) {
if ($this->Row - 1 == $pos) {
$this->ora_no_next_fetch=true;
} elseif ($this->Row == $pos ) {
## 아무것도 하지 않음
} 다른 {
$this->halt("잘못된 탐색(): 위치는 API에서 처리할 수 없습니다.
".
"이 버전에서는 마지막 요소 탐색만 허용됩니다
".
"차이가 너무 큽니다. 구함: $pos 현재 위치: $this->Row");
}
if ($this->Debug) echo "
디버그: 탐색 = $pos
";
$this->행=$pos;
}
function lock($table, $mode = "write") {
if ($mode == "쓰기") {
$result = ora_do($this->Link_ID, "행 배타적 모드에서 $table 테이블 잠금");
} 다른 {
$결과 = 1;
}
$결과를 반환합니다.
}
함수 잠금 해제() {
return ora_do($this->Link_ID, "커밋");
}
// 중요 참고 사항: 이 함수는 Oracle-Database-Links에서는 작동하지 않습니다!
// 더 나은 방법을 자유롭게 얻을 수 있습니다. :)
함수 메타데이터($table,$full=false) {
$카운트 = 0;
$ID = 0;
$res = 배열();
/*
* Table과의 호환성 문제로 인해 동작을 변경했습니다
* 메타데이터();
* $full에 따라 메타데이터는 다음 값을 반환합니다.
*
* - 전체가 거짓임(기본값):
* $결과[]:
* [0]["table"] 테이블 이름
* [0]["name"] 필드 이름
* [0]["type"] 필드 유형
* [0]["len"] 필드 길이
* [0]["flags"] 필드 플래그("NOT NULL", "INDEX")
* [0]["format"] 숫자의 정밀도 및 소수 자릿수(예: "10,2") 또는 비어 있음
* [0]["index"] 인덱스 이름(있는 경우)
* [0]["chars"] 문자 수(문자 유형인 경우)
*
* - 전체가 사실입니다
* $결과[]:
* ["num_fields"] 메타데이터 레코드 수
* [0]["table"] 테이블 이름
* [0]["name"] 필드 이름
* [0]["type"] 필드 유형
* [0]["len"] 필드 길이
* [0]["flags"] 필드 플래그("NOT NULL", "INDEX")
* [0]["format"] 숫자의 정밀도 및 소수 자릿수(예: "10,2") 또는 비어 있음
* [0]["index"] 인덱스 이름(있는 경우)
* [0]["chars"] 문자 수(문자 유형인 경우)
* [0]["php_type"] 해당 PHP 유형
* [0]["php_subtype"] PHP 유형의 하위 유형
* ["meta"][필드 이름] "필드 이름"이라는 필드의 인덱스
* 이름은 있지만 색인 번호가 없는 경우 사용할 수 있습니다. 매우 빠릅니다.
* 테스트: if (isset($result['meta']['myfield'])) {} ...
*/
$this->connect();
## 이것은 RIGHT OUTER JOIN입니다: "(+)", 보고 싶다면
## 이 쿼리 결과는 다음을 시도해 보세요.
## $table = 새 테이블; $db = 새로운 my_DB_Sql; #
만들어야 해
## # 나만의 수업
## $table->show_results($db->query(쿼리 vvvvvv 참조))
##
$this->query("SELECT T.table_name,T.column_name,T.data_type,".
"T.data_length,T.data_precision,T.data_scale,T.nullable,".
"T.char_col_decl_length,I.index_name".
" ALL_TAB_COLUMNS T, ALL_IND_COLUMNS I"에서.
" WHERE T.column_name=I.column_name (+)".
" AND T.table_name=I.table_name (+)".
" AND T.table_name=UPPER('$table') ORDER BY T.column_id");
$i=0;
while ($this->next_record()) {
$res[$i]["table"] = $this->기록[table_name];
$res[$i]["name"] = strtolower($this->Record[column_name]);
$res[$i]["type"] = $this->기록[data_type];
$res[$i]["len"] = $this->기록[data_length];
if ($this->Record[index_name]) $res[$i]["flags"] = "INDEX ";
$res[$i]["flags"] .= ( $this->Record[nullable] == 'N') ? '' : 'NULL이 아님';
$res[$i]["format"]= (int)$this->기록[data_precision].",".
(int)$this->기록[data_scale];
if ("0,0"==$res[$i]["format"]) $res[$i]["format"]='';
$res[$i]["index"] = $this->기록[index_name];
$res[$i]["chars"] = $this->기록[char_col_decl_length];
if ($full) {
$j=$res[$i]["이름"];
$res["meta"][$j] = $i;
$res["meta"][strtoupper($j)] = $i;
스위치 ($res[$i]["type"]) {
케이스 "VARCHAR2":
케이스 "VARCHAR":
케이스 "CHAR" :
$res["php_type"]="문자열";
$res["php_subtype"]="";
부서지다;
사례 "날짜":
$res["php_type"]="문자열";
$res["php_subtype"]="날짜";
부서지다;
케이스 "BLOB":
케이스 "CLOB" :
케이스 "BFILE" :
케이스 "RAW":
케이스 "LONG":
케이스 "LONG RAW":
$res["php_type"]="문자열";
$res["php_subtype"]="블롭";
부서지다;
케이스 "NUMBER":
if ($res[$i]["형식"]) {
$res["php_type"]="더블";
$res["php_subtype"]="";
} 다른 {
$res["php_type"]="int";
$res["php_subtype"]="";
}
부서지다;
기본값 :
$this->halt("metadata(): 유형은 유효한 값이 아닙니다: '$res[$i][type]'");
부서지다;
}
}
if ($full) $res["meta"][$res[$i]["name"]] = $i;
$i++;
}
if ($full) $res["num_fields"]=$i;
# $this->disconnect();
$res를 반환합니다.
}
## 이 기능은 테스트되지 않았습니다!
함수 영향을 받은_rows() {
if ($this->Debug) echo "
디버그: 영향을 받은_rows=". ora_numrows($this->Query_ID)."
";
return ora_numrows($this->Query_ID);
}
## 알려진 버그: SELECT DISTINCT 및 모든
에서는 작동하지 않습니다.
## 결과 행에 따라 달라지는 다른 구성.
## 따라서 모든 검색어를 확인해야 *정말* 필요합니다.
## 그걸로 작동합니다!
##
## 또한 적격한 교체를 위해서는
을 구문 분석해야 합니다.
## 선택, 실패합니다: "SELECT id, from FROM ...").
## "from"은 - 제가 Oracle에서 아는 한 키워드이므로
## 이 방법으로만 사용하세요. 그러나 당신은 경고를 받았습니다.
함수 num_rows() {
$curs=ora_open($this->Link_ID);
## 이것이 중요한 부분이자 HACK이기도 합니다!
if (eregi("^[[:space:]]*SELECT[[:space:]]",$this->lastQuery) )
{
# 모두에게 효과가 있나요?? SELECT DISTINCT 케이스를 포함한 케이스.
# 원래 SQL 표현식에서 select count(*)를 만듭니다
# 속도를 위해 ORDER BY(있는 경우)를 제거합니다
# 저도 정규 표현식을 좋아해요 ;-)))
$q = sprintf("(%s)에서 COUNT(*) 선택",
@eregi_Replace("ORDER[[:space:]]+BY[^)]*()*)", "1",
$this->lastQuery)
);
# 하위 선택에도 작동합니다:
# if (eregi("[[:space:]]+FROM([[:space:]]+.*[[:space:]]+FROM)",$this->lastQuery,$r))
# $areplace=$r[1];
# $q=eregi_Replace("^[[:space:]]*SELECT[[:space:]]+".
# ".*[[:space:]]+FROM",
# "SELECT COUNT(*) FROM$areplace",
# $this->lastQuery);
if ($this->Debug) echo "
디버그: num_rows: $q
";
ORA_parse($curs,$q);
ORA_exec($curs);
ORA_fetch($curs);
$result = ORA_getcolumn($curs,0);
ORA_close($curs);
if ($this->디버그)
{
echo "
디버그: ID ".$this->QueryID.
" num_rows=". $결과 ."
";
}
$결과를 반환합니다.
}
그렇지 않으면
{
$this->halt("마지막 쿼리는 SELECT가 아닙니다: $this->lastQuery");
}
}
함수 num_fields() {
if ($this->Debug) echo "
디버그: num_fields=". ora_numcols($this->Query_ID) . "
";
return ora_numcols($this->Query_ID);
}
함수 nf() {
$this->num_rows()를 반환합니다.
}
함수 np() {
$this->num_rows()를 인쇄합니다.
}
함수 f($Name) {
return $this->레코드[$Name];
}
함수 p($Name) {
$this->기록[$Name] 인쇄;
}
/* 공개: 시퀀스 번호 */
함수 nextid($seq_name)
{
$this->connect();
/* 독립 쿼리_ID */
$Query_ID = ora_open($this->Link_ID);
if(!@ora_parse($Query_ID,"SELECT $seq_name.NEXTVAL FROM DUAL"))
{
// 아직 그런 시퀀스가 없다면 생성하세요
if(!@ora_parse($Query_ID,"CREATE SEQUENCE $seq_name")
||
!@ora_exec($Query_ID)
)
{
$this->halt("
nextid() 함수 - 시퀀스를 생성할 수 없습니다.");
0을 반환합니다.
}
@ora_parse($Query_ID,"SELECT $seq_name.NEXTVAL FROM DUAL");
}
if (!@ora_exec($Query_ID)) {
$this->halt("
ora_exec() 실패:
nextID 함수");
}
if (@ora_fetch($Query_ID) ) {
$next_id = ora_getcolumn($Query_ID, 0);
}
그렇지 않으면 {
$next_id = 0;
}
if ( $Query_ID > 0 ) {
ora_close($Query_ID);
}
$next_id를 반환합니다.
}
함수 연결 끊기() {
if($this->Debug) {
echo "디버그: $this->Query_ID 연결을 끊는 중...
n";
}
if ( $this->Query_ID
echo "경고: 연결 끊기(): $this->Query_IDn ID를 해제할 수 없습니다.";
# 반품();
}
ora_close($this->Query_ID);
$this->Query_ID=0;
}
/* 비공개: 오류 처리 */
기능 정지($msg) {
if ($this->Halt_On_Error == "아니요")
반품;
$this->haltmsg($msg);
if ($this->Halt_On_Error != "보고")
die("세션이 중단되었습니다.");
}
함수 quitmsg($msg) {
printf("
데이터베이스 오류: %s
n", $msg);
printf("오라클 오류: %s (%s)
n",
$this->Errno,
$this->오류);
}
function table_names() {
$this->connect();
$this->query("
SELECT 테이블_이름,테이블스페이스_이름
FROM user_tables");
$i=0;
while ($this->next_record())
{
$info[$i]["table_name"] =$this->기록["table_name"];
$info[$i]["tablespace_name"]=$this->레코드["tablespace_name"];
$i++;
}
$정보를 반환합니다.
}
// 일부 거래 지원
// ct_oracle.inc에서 사용되는 메소드
함수 start_transaction()
{
$this->connect();
// 이제 자동 커밋을 비활성화합니다
Ora_CommitOff($this->Link_ID);
if ($this->디버그)
{
"BEGIN TRANSACTION
"을 인쇄합니다.
}
}
함수 end_transaction()
{
if ($this->디버그)
{
"BEGIN TRANSACTION
"을 인쇄합니다.
}
$res = 1;
if(!@Ora_Commit($this->Link_ID))
{
Ora_CommitOn($this->Link_ID);
$this->halt("거래를 완료할 수 없습니다.");
$res = 0;
}
// 자동 커밋을 다시 활성화합니다
Ora_CommitOn($this->Link_ID);
if ($this->디버그)
{
"END TRANSACTION : $res
"를 인쇄합니다.
}
$res를 반환합니다.
}
}
?>

PHP는 현대적인 프로그래밍, 특히 웹 개발 분야에서 강력하고 널리 사용되는 도구로 남아 있습니다. 1) PHP는 사용하기 쉽고 데이터베이스와 완벽하게 통합되며 많은 개발자에게 가장 먼저 선택됩니다. 2) 동적 컨텐츠 생성 및 객체 지향 프로그래밍을 지원하여 웹 사이트를 신속하게 작성하고 유지 관리하는 데 적합합니다. 3) 데이터베이스 쿼리를 캐싱하고 최적화함으로써 PHP의 성능을 향상시킬 수 있으며, 광범위한 커뮤니티와 풍부한 생태계는 오늘날의 기술 스택에 여전히 중요합니다.

PHP에서는 약한 참조가 약한 회의 클래스를 통해 구현되며 쓰레기 수집가가 물체를 되 찾는 것을 방해하지 않습니다. 약한 참조는 캐싱 시스템 및 이벤트 리스너와 같은 시나리오에 적합합니다. 물체의 생존을 보장 할 수 없으며 쓰레기 수집이 지연 될 수 있음에 주목해야합니다.

\ _ \ _ 호출 메소드를 사용하면 객체를 함수처럼 호출 할 수 있습니다. 1. 객체를 호출 할 수 있도록 메소드를 호출하는 \ _ \ _ 정의하십시오. 2. $ obj (...) 구문을 사용할 때 PHP는 \ _ \ _ invoke 메소드를 실행합니다. 3. 로깅 및 계산기, 코드 유연성 및 가독성 향상과 같은 시나리오에 적합합니다.

섬유는 PHP8.1에 도입되어 동시 처리 기능을 향상시켰다. 1) 섬유는 코 루틴과 유사한 가벼운 동시성 모델입니다. 2) 개발자는 작업의 실행 흐름을 수동으로 제어 할 수 있으며 I/O 집약적 작업을 처리하는 데 적합합니다. 3) 섬유를 사용하면보다 효율적이고 반응이 좋은 코드를 작성할 수 있습니다.

PHP 커뮤니티는 개발자 성장을 돕기 위해 풍부한 자원과 지원을 제공합니다. 1) 자료에는 공식 문서, 튜토리얼, 블로그 및 Laravel 및 Symfony와 같은 오픈 소스 프로젝트가 포함됩니다. 2) 지원은 StackoverFlow, Reddit 및 Slack 채널을 통해 얻을 수 있습니다. 3) RFC에 따라 개발 동향을 배울 수 있습니다. 4) 적극적인 참여, 코드에 대한 기여 및 학습 공유를 통해 커뮤니티에 통합 될 수 있습니다.

PHP와 Python은 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1.PHP는 간단한 구문과 높은 실행 효율로 웹 개발에 적합합니다. 2. Python은 간결한 구문 및 풍부한 라이브러리를 갖춘 데이터 과학 및 기계 학습에 적합합니다.

PHP는 죽지 않고 끊임없이 적응하고 진화합니다. 1) PHP는 1994 년부터 새로운 기술 트렌드에 적응하기 위해 여러 버전 반복을 겪었습니다. 2) 현재 전자 상거래, 컨텐츠 관리 시스템 및 기타 분야에서 널리 사용됩니다. 3) PHP8은 성능과 현대화를 개선하기 위해 JIT 컴파일러 및 기타 기능을 소개합니다. 4) Opcache를 사용하고 PSR-12 표준을 따라 성능 및 코드 품질을 최적화하십시오.

PHP의 미래는 새로운 기술 트렌드에 적응하고 혁신적인 기능을 도입함으로써 달성 될 것입니다. 1) 클라우드 컴퓨팅, 컨테이너화 및 마이크로 서비스 아키텍처에 적응, Docker 및 Kubernetes 지원; 2) 성능 및 데이터 처리 효율을 향상시키기 위해 JIT 컴파일러 및 열거 유형을 도입합니다. 3) 지속적으로 성능을 최적화하고 모범 사례를 홍보합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.
