자바스크립트를 활성화 해주세요

p061 Powershell 에서 Php 코드 실행시키기 Invoke-PHPScript

 ·  ☕ 3 min read

뭘 이렇게 까지 해야 할 필요가 있을까 싶습니다만,

Invoke-PHPScript 정의

1
2
3
4
5
6
7
filter Invoke-PHPScript(){
    $tempfile = [System.IO.Path]::GetTempFileName()
    $encoding = [System.Text.Encoding]::GetEncoding("utf-8")
    ;[System.IO.File]::WriteAllText($tempfile,$_,$encoding)
    php -f $tempfile
    del $tempfile
}

사용은 이렇게 합니다.

1
2
3
4
5
@"
<?php
  echo "hell world";
?>
"@ | Invoke-PHPScript

php의 readfile을 사용한다면 Invoke-WebRequest와 같은 기능의 함수를 만들 수 있습니다.

파일계 함수

readfile 함수

1
2
3
4
5
6
7
function readfile($filename){
@"
<?php
  readfile('$filename')."\n";
?>
"@ | Invoke-PHPScript
}

예를 들면 다음과 같은 코드를 실행할 수 있습니다.

1
readfile http://m.daum.net

실행한 결과는 다음과 같습니다.

p061_invoke-phpscript_readfile.png

php의 기능을 잉용하는 코드를 작성할 수도 있습니다. 예를 들면

배열계 함수

array_diff 함수

1
2
3
4
5
6
7
8
function array_diff(){
  $str_array = ($args | foreach{'array(' + (($_ | foreach{"'$_'"}) -join ',') + ')'}) -join ','
@"
<?php
  echo join("\n",array_diff($str_array))."\n";
?>
"@ | Invoke-PHPScript
}

결과

array_diff ('A','B','C') ('A','C','D')
# -> B

array_intersect 함수

1
2
3
4
5
6
7
8
function array_intersect(){
  $str_array = ($args | foreach{'array(' + (($_ | foreach{"'$_'"}) -join ',') + ')'}) -join ','
@"
<?php
  echo join("\n",array_intersect($str_array))."\n";
?>
"@ | Invoke-PHPScript
}

결과

array_intersect ('A','B','C') ('A','C','D')
# -> A
#    C

natsort 와 natcasesort 함수

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function natsort(){
  $str_array = ('array(' + (($input | foreach{"'$_'"}) -join ',') + ')')
  $def_var = '$a = ' + $str_array + ';'
@'
<?php 
'@ + $def_var + @'
  natsort($a);
  echo join("\n",$a)."\n";
?>
'@ | Invoke-PHPScript
}

function natcasesort(){
  $str_array = ('array(' + (($input | foreach{"'$_'"}) -join ',') + ')')
  $def_var = '$a = ' + $str_array + ';'
@'
<?php 
'@ + $def_var + @'
  natcasesort($a);
  echo join("\n",$a)."\n";
?>
'@ | Invoke-PHPScript
}

결과

('10 Apple','1 Orange','3 Banana','1 apple') | natsort
# -> 1 Orange
#    1 apple
#    3 Banana
#    10 Apple

('10 Apple','1 Orange','3 Banana','1 apple') | natcasesort
# -> 1 apple
#    1 Orange
#    3 Banana
#    10 Apple

문자계열 함수

number_format 함수

1
2
3
4
5
6
7
filter number_format($decimals = 0,$dec_point = ".",$thousands_sep = ","){
@"
<?php
  echo number_format('$_',$decimals,'$dec_point','$thousands_sep')."\n";
?>
"@ | Invoke-PHPScript
}

결과

'$' + (1000 | number_format 2)
# -> $1,000.00

sscanf 함수

1
2
3
4
5
6
7
filter sscanf($format){
@"
<?php
  echo join("\n",sscanf("$_", "$format"))."\n";
?>
"@ | Invoke-PHPScript
}

결과

"2015년11월22일" | sscanf "%d년%d월%d일"
# -> 2015
#    11
#    22

strspn 함수

1
2
3
4
5
6
7
filter strspn($mask){
@"
<?php
  echo strspn('$_','$mask')."\n";
?>
"@ | Invoke-PHPScript
}

결과

"0923 abc" | strspn "0123456789"
# -> 4

"abc 0923" | strspn "0123456789"
# -> 0

strcspn 함수

1
2
3
4
5
6
7
filter strcspn($mask){
@"
<?php
  echo strcspn('$_','$mask')."\n";
?>
"@ | Invoke-PHPScript
}

결과

"0923 abc" | strcspn "0123456789"
# -> 0

"abc 0923" | strcspn "0123456789"
# -> 4

strtr 함수

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
filter strtr($replace_pairs){
  $str_replace_pairs = `
    if(($replace_pairs | foreach{$_.GetType().Name}).Contains('Object[]')){
      ($replace_pairs | foreach{($_ | foreach{"'$_'"}) -join '=>'}) -join ','
    } else {
      ($replace_pairs | foreach{"'$_'"}) -join '=>'
    }
@"
<?php
  echo strtr('$_', array($str_replace_pairs))."\n";
?>
"@ | Invoke-PHPScript
}

결과

'(^_^)' | strtr ('^','+')
# -> (+_+)

'(^_^)' | strtr ('^','/'),('_','/')
# -> (///)

substr_replace 함수

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
filter substr_replace($replacement,$start,$length = 0){
  if($length -eq 0){
@"
<?php
  echo substr_replace('$_', '$replacement', $start)."\n";
?>
"@ | InvokePHPScript
} else {
@"
<?php
  echo substr_replace('$_', '$replacement', $start, $length)."\n";
?>
"@ | Invoke-PHPScript
  }
}

결과

'0000000000' | substr_replace '1' 2 1
# -> 0010000000

ucfirst 함수

1
2
3
4
5
6
7
filter ucfirst(){
@"
<?php
  echo ucfirst('$_')."\n";
?>
"@ | Invoke-PHPScript
}

결과

'how are you?' | ucfirst
# -> How are you?

ucwords 함수

1
2
3
4
5
6
7
filter ucwords(){
@"
<?php
  echo ucwords('$_')."\n";
?>
"@ | Invoke-PHPScript
}

결과

'who am i?' | ucwords
# -> Who Am I?

sqlite3 계열 함수

php.ini의 php_sqlite3.dll (extension)을 이용가능하게 설정할 필요가 있습니다.

exec 함수

1
2
3
4
5
6
filter sqlite3_exec($path){
  '<?php' + "`n" + `
  '$db = new SQLite3(' + "'$path'" + ');' + "`n" + `
  '$db->exec(' + "'$_'" + ');' + "`n" + `
  '?>' | Invoke-PHPScript
}

query 함수

1
2
3
4
5
6
7
8
9
filter sqlite3_query($path,$delimiter = ','){
  '<?php' + "`n" + `
  '$db = new SQLite3(' + "'$path'" + ');' + "`n" + `
  '$result = $db->query(' + "'$_'" + ');' + "`n" + `
  'while($row = $result->fetchArray(SQLITE3_ASSOC)){' + "`n" + `
  '  echo join("' + $delimiter + '",$row)."\n";' + "`n" + `
  '}' + "`n" + `
  '?>' | Invoke-PHPScript
}

php에서 powershell 호출

거꾸로 php안에서 powershell을 호출한다면, 다음중 하나를 선택해서 사용하면 됩니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
shell_exec('pwsh -File /your/path/to/file.ps1');
 
// Or
exec('pwsh -File /your/path/to/file.ps1');
 
// Or
system('pwsh -File /your/path/to/file.ps1');
 
// Or
passthru('pwsh -File /your/path/to/file.ps1');

만일 non-blocking으로 실행해야 한다면? background로 실행하면 됩니다.

1
shell_exec('pwsh -File /your/path/to/file.ps1 > /dev/null 2>&1 &');

결론, 굳이 사용하실 필요는 없습니다만, 간혹, 서로의 장점을 이용하는 경우, 또는 타 언어와의 조합을 원하는 경우에 참고하시면 좋을 것 같습니다.

공유하기

tkim
글쓴이
tkim
Software Engineer