HEYBlog about Technology

京都の学生エンジニアのエンジニアブログ

PHP curlで、ファイルアップロードして、Ruby Sinatraで受け取る

PHPで動かしているプロジェクトから、 Sinatraで動かしているプロジェクトに画像を転送しないといけない事案が発生したので書いてみた。

PHPの送信側

<?php

    $path = "./images/hoge.png";

    if(!file_exists($path)) {
        print "can't get image\n";
        return false;
    }

    $url = "アップロード先IP";
    $params = array('file'=>"@$path;type=image/png");

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, TRUE );
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params );
    curl_exec($ch);
    curl_close($ch);


?>

ポイント

①$params = array('file'=>"@$path;type=image/png");

MIME TYPEの設定は;type=〇〇で書く。

ファイルを指定するときはアットマークを最初に書かなければならない

Sinatoraで動かしているプロジェクトで画像を受け取る

main.rb

# -*- coding: utf-8 -*-
require 'sinatra'
require 'erb'
#set :public_folder, File.dirname(__FILE__) + '/images/'

class MainApp < Sinatra::Base

  # アップロード処理
  post '/upload' do
    image_name =''
    unless params[:file]
      halt 400, 'No file'
    end

    image_name = params[:file][:filename]
    save_path = './images/'+image_name
    
    begin
      File.open(save_path, 'wb') do |f|
        p params[:file][:tempfile]
        f.write params[:file][:tempfile].read
      end
    rescue
      #No image 404
      halt 404, 'No file'
    end
    
    redirect image_name
  end

 
end

Debianでネットワークの設定した

ネットワークの設定方法(Debian)

固定IPにする

emacs /etc/network/interfaces
auto lo
   iface lo inet loopback
   auto eth0
   iface eth0 inet static
     address 192.168.0.11
     netmask 255.255.255.0
     gateway 192.168.0.1

gatewayどうすればよいの?ってときは

/sbin/route

Gatewayの値を見れば良い

ネットワーク設定再起動

sudo /etc/init.d/networking restart

ifconfigでeth0が立ち上がってなかったら

ifup eth0

eth0がNo such device

ifconfig -a

でチェックする eth1が立ち上がっていることがあった。

Ruby Sinatoraの基礎

ruby Sinatra

最小構成

main.rb
Gemfile
public
    images
views
config.ru

post get

post '/upload' do
    p ('hoge')
end

get '/images' do
    p ('hello')
end
    

image/hoge.png等の正規表現

get '/image/*' do
    p (params[:splat]) #=>hoge.png
end

get '/say/*/to/*' do
  # matches /say/hello/to/world
  params[:splat] # => ["hello", "world"]
end

get '/download/*.*' do
  # matches /download/path/to/file.xml
  params[:splat] # => ["path/to/file", "xml"]
end

get %r{^/([0-9a-f]{32}\.png)} do |image_name|
    p (image_name)
end

最後の正規表現のルーティングはパイプに入れたいものは()で閉じてあげる そうじゃないと Argument Errorで落ちる

文字列連結

hoge_1 = 'ho' + 'ge'
p (hoge_1)
hoge_2 = 'h'
hoge_2 <<'o'
hoge_2 <<'ge'
p (hoge_2)

ho = 'ho'
kyoto = 'kyoto'
hoge ="#{ho}ge#{kyoto}"

文字列置換

hoge ='hoge_sample'
new_hoge = hoge.gsub('sample','kyoto')
p (hoge) # -->hoge_kyoto

ルーティング正規表現

get %r{/[0-9a-f]{32}} do #OK
end

get %r{^/[0-9a-f]{32}} do #NG
end

^が大事。 ^がないと /00/0000c77b2fbd66dc65eaf09309873eb3 でも通ることになる

erbテンプレートとの連携

main.rb

get '/hoge' do
    @hoge ='hogeだこのやろう'
    erb:images
end

views/images.erb

  <p><%= @hoge%></p>

Sinatraで画像のバイナリデータを送る

data = nil
  File.open(image_path, 'rb') do |f|
    data = f.read
  end

  content_type "image/png"
  data

returnとかいちいち書かなくてええのが良いね!

アップロード処理

                                               
post '/upload' do
  image_name =''
  if params[:file]

    save_path = "./public/images/#{params[:file][:filename]}"
    image_name = params[:file][:filename]
    File.open(save_path, 'wb') do |f|
      p params[:file][:tempfile]
      f.write params[:file][:tempfile].read
      @mes = "アップロード成功"
      end
  else
    @mes = "アップロード失敗"
  end
  haml :upload
  #gsub パターンにマッチした部分をすべて指定の文字列に置換する                
  redirect 'images/'+image_name
end


 # アップロードした画像の表示                                                  
get '/images/*' do

  @image_path    =params[:image_path]
  haml :images
end

view関連 image.haml

!!!html5
%html
 %body
   %img{:src => @images_path}