2013-05-22 3 views
3

У меня есть приложение для Android, которое отправляет данные через HTTP POST-метод скрипту PHP и пытается проанализировать данные для хранения в MySQL. Приложение Android не было написано мной, но у меня есть доступ к исходному коду, который я включил ниже; он отправляет данные, упакованные как массив JSON. Мой PHP скрипт прямо сейчас пытается поместить данные как в текстовом файле и в БД MySQL:PHP Вставка данных JSON в базу данных MySQL с Android

<?php 

    $con=mysqli_connect("localhost","dbname","dbpassword","table"); 
    if (mysqli_connect_errno()) 
    { 
    echo "Failed to connect to MySQL DB: " . mysqli_connect_error(); 
    } 

    $filename = __DIR__.DIRECTORY_SEPARATOR."jsontest.txt"; 

    $postdata = file_get_contents("php://input"); 
    $data = json_decode($postdata, true); 


    //if (array_key_exists('records', $data) && is_array($data['records'])) { 
    //above if loop threw warning "array_key_exists() expects parameter 2 to be array, null given" 

    if (is_array($data['records'])) { 
     foreach ($data['records'] as $record) { 
     $name = $record['name']; 
     $value = $record['value']; 
    $event = $record['event']; 
     $timestamp = $record['timestamp']; 

     file_put_contents($filename, "$name -> $value with event: $event at $timestamp\n", FILE_APPEND); 
     mysqli_query($con,"INSERT INTO `Driving Data`(`Name`, `Value`, `Event`, `Timestamp`) VALUES ($name, $value, $event, $timestamp)"); 
     } 
    } 

    mysqli_close($con); 
?> 

в текстовый файл распечатывает все данные, как я сказать ему. Однако база данных никогда не обновляется. База данных устанавливается следующим образом:

CREATE TABLE `Driving Data` (
`Name` varchar(75) NOT NULL, 
`Value` varchar(40) NOT NULL, 
`Event` varchar(20) NOT NULL, 
`Timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

Вот как пример данных JSON выглядит:

{"records":[{"name":"accelerator_pedal_position","value":15.400001,"timestamp":1367598908.278000},{"name":"engine_speed","value":1716.0,"timestamp":1367598908.285000},{"name":"vehicle_speed","value":32.040001,"timestamp":1367598908.290000},{"name":"brake_pedal_status","value":false,"timestamp":1367598908.293000},{"name":"fuel_consumed_since_restart","value":0.147325,"timestamp":1367598908.301000},{"name":"transmission_gear_position","value":"third","timestamp":1367598908.304000},{"name":"steering_wheel_angle","value":-2.3733,"timestamp":1367598908.307000},{"name":"fuel_consumed_since_restart","value":0.14745,"timestamp":1367598908.314000},{"name":"transmission_gear_position","value":"third","timestamp":1367598908.317000},{"name":"door_status","value":"driver","event":false,"timestamp":1367598908.320000},{"name":"door_status","value":"passenger","event":false,"timestamp":1367598908.326000},{"name":"door_status","value":"rear_left","event":false,"timestamp":1367598908.329000},{"name":"door_status","value":"rear_right","event":false,"timestamp":1367598908.331000},{"name":"odometer","value":0.0,"timestamp":1367598908.338000},{"name":"high_beam_status","value":false,"timestamp":1367598908.341000},{"name":"steering_wheel_angle","value":-2.3733,"timestamp":1367598908.343000},{"name":"engine_speed","value":1716.0,"timestamp":1367598908.351000},{"name":"powertrain_torque","value":74.0,"timestamp":1367598908.358000},{"name":"accelerator_pedal_position","value":12.1,"timestamp":1367598908.364000},{"name":"latitude","value":42.293911,"timestamp":1367598908.367000},{"name":"longitude","value":-83.238762,"timestamp":1367598908.376000},{"name":"engine_speed","value":1718.0,"timestamp":1367598908.380000},{"name":"vehicle_speed","value":32.200001,"timestamp":1367598908.382000},{"name":"brake_pedal_status","value":false,"timestamp":1367598908.391000},{"name":"transmission_gear_position","value":"third","timestamp":1367598908.393000}]} 

Так что я относительно новым для PHP, и я не могу показаться, чтобы выяснить, что проблема заключается в том, почему база данных не обновляется этими значениями, но она все равно может записать их в текстовый файл. Для справки ниже приведен код Android, используемый для отправки данных на веб-сервер (я не могу это изменить):

public class UploaderSink extends ContextualVehicleDataSink { 
private final static String TAG = "UploaderSink"; 
private final static int UPLOAD_BATCH_SIZE = 25; 
private final static int MAXIMUM_QUEUED_RECORDS = 5000; 
private final static int HTTP_TIMEOUT = 5000; 

private URI mUri; 
private BlockingQueue<String> mRecordQueue = 
     new LinkedBlockingQueue<String>(MAXIMUM_QUEUED_RECORDS); 
private Lock mQueueLock = new ReentrantLock(); 
private Condition mRecordsQueued = mQueueLock.newCondition(); 
private UploaderThread mUploader = new UploaderThread(); 

/** 
* Initialize and start a new UploaderSink immediately. 
* 
* @param uri the URI to send HTTP POST requests to with the JSON data. 
*/ 
public UploaderSink(Context context, URI uri) { 
    super(context); 
    mUri = uri; 
} 

public UploaderSink(Context context, String path) throws DataSinkException { 
    this(context, uriFromString(path)); 
} 

@Override 
public void stop() { 
    super.stop(); 
    mUploader.done(); 
} 

public boolean receive(RawMeasurement measurement) { 
    String data = measurement.serialize(true); 
    mRecordQueue.offer(data); 
    if(mRecordQueue.size() >= UPLOAD_BATCH_SIZE) { 
     mQueueLock.lock(); 
     mRecordsQueued.signal(); 
     mQueueLock.unlock(); 
    } 
    return true; 
} 

/** 
* Returns true if the path is not null and if it is a valid URI. 
* 
* @param path a URI to validate 
* @return true if path is a valid URI. 
* 
*/ 
public static boolean validatePath(String path) { 
    if(path == null) { 
     Log.w(TAG, "Uploading path not set (it's " + path + ")"); 
     return false; 
    } 

    try { 
     uriFromString(path); 
     return true; 
    } catch(DataSinkException e) { 
     return false; 
    } 
} 

@Override 
public String toString() { 
    return Objects.toStringHelper(this) 
     .add("uri", mUri) 
     .add("queuedRecords", mRecordQueue.size()) 
     .toString(); 
} 

private static URI uriFromString(String path) throws DataSinkException { 
    try { 
     return new URI(path); 
    } catch(java.net.URISyntaxException e) { 
     throw new UploaderException(
      "Uploading path in wrong format -- expected: ip:port"); 
    } 
} 

private static class UploaderException extends DataSinkException { 
    private static final long serialVersionUID = 7436279598279767619L; 

    public UploaderException() { } 

    public UploaderException(String message) { 
     super(message); 
    } 
} 

private class UploaderThread extends Thread { 
    private boolean mRunning = true; 

    public UploaderThread() { 
     start(); 
    } 

    public void run() { 
     while(mRunning) { 
      try { 
       ArrayList<String> records = getRecords(); 
       String data = constructRequestData(records); 
       HttpPost request = constructRequest(data); 
       makeRequest(request); 
      } catch(UploaderException e) { 
       Log.w(TAG, "Problem uploading the record", e); 
      } catch(InterruptedException e) { 
       Log.w(TAG, "Uploader was interrupted", e); 
       break; 
      } 
     } 
    } 

    public void done() { 
     mRunning = false; 
    } 

    private String constructRequestData(ArrayList<String> records) 
      throws UploaderException { 
     StringWriter buffer = new StringWriter(512); 
     JsonFactory jsonFactory = new JsonFactory(); 
     try { 
      JsonGenerator gen = jsonFactory.createJsonGenerator(buffer); 

      gen.writeStartObject(); 
      gen.writeArrayFieldStart("records"); 
      Iterator<String> recordIterator = records.iterator(); 
      while(recordIterator.hasNext()) { 
       gen.writeRaw(recordIterator.next()); 
       if(recordIterator.hasNext()) { 
        gen.writeRaw(","); 
       } 
      } 
      gen.writeEndArray(); 
      gen.writeEndObject(); 

      gen.close(); 
     } catch(IOException e) { 
      Log.w(TAG, "Unable to encode all data to JSON -- " + 
        "message may be incomplete", e); 
      throw new UploaderException(); 
     } 
     return buffer.toString(); 
    } 

    private HttpPost constructRequest(String data) 
      throws UploaderException { 
     HttpPost request = new HttpPost(mUri); 
     try { 
      ByteArrayEntity entity = new ByteArrayEntity(
        data.getBytes("UTF8")); 
      entity.setContentEncoding(
        new BasicHeader("Content-Type", "application/json")); 
      request.setEntity(entity); 
     } catch(UnsupportedEncodingException e) { 
      Log.w(TAG, "Couldn't encode records for uploading", e); 
      throw new UploaderException(); 
     } 
     return request; 
    } 

    private void makeRequest(HttpPost request) throws InterruptedException { 
     HttpParams parameters = new BasicHttpParams(); 
     HttpConnectionParams.setConnectionTimeout(parameters, HTTP_TIMEOUT); 
     HttpConnectionParams.setSoTimeout(parameters, HTTP_TIMEOUT); 
     final HttpClient client = new DefaultHttpClient(parameters); 
     try { 
      HttpResponse response = client.execute(request); 
      final int statusCode = response.getStatusLine().getStatusCode(); 
      if(statusCode != HttpStatus.SC_CREATED) { 
       Log.w(TAG, "Got unxpected status code: " + statusCode); 
      } 
     } catch(IOException e) { 
      Log.w(TAG, "Problem uploading the record", e); 
      try { 
       Thread.sleep(5000); 
      } catch(InterruptedException e2) { 
       Log.w(TAG, "Uploader interrupted after an error", e2); 
       throw e2; 
      } 
     } 
    } 

    private ArrayList<String> getRecords() throws InterruptedException { 
     mQueueLock.lock(); 
     if(mRecordQueue.isEmpty()) { 
      // the queue is already thread safe, but we use this lock to get 
      // a condition variable we can use to signal when a batch has 
      // been queued. 
      mRecordsQueued.await(); 
     } 

     ArrayList<String> records = new ArrayList<String>(); 
     mRecordQueue.drainTo(records, UPLOAD_BATCH_SIZE); 

     mQueueLock.unlock(); 
     return records; 
    } 
} 
+0

Передающего код не должен иметь значения, только принимающий код и входной данные. Пожалуйста, разместите свою строку запроса в форме, которую она запускает со всеми введенными входными переменными. – dutt

+0

Вы должны добавить проверку ошибок для mysqli_query, это поможет вам отладить проблему. http://php.net/manual/en/mysqli.query.php – 1615903

+0

Какая ошибка вы получаете? Также укажите свой тип данных в столбцах таблицы. –

ответ

2

попытка Преобразование Отметки времени Unix для тузда метки времени

if (is_array($data['records'])) { 
    foreach ($data['records'] as $record) { 
    $name = $record['name']; 
    $value = $record['value']; 
$event = $record['event']; 
    $timestamp = date('Y-m-d H:i:s',$record['timestamp']); 

    file_put_contents($filename, "$name -> $value with event: $event at $timestamp\n", FILE_APPEND); 
    mysqli_query($con,"INSERT INTO `Driving Data`(`Name`, `Value`, `Event`, `Timestamp`) VALUES ($n 

ame, $value, $event, $timestamp)"); 
     } 
    } 
+0

Это вызывало у меня проблему, временная метка была не в правильном формате. Спасибо за помощь! – mbecker73

0

Прямо сейчас, просто глядя на ваш код, у вас есть VALUES, написанные дважды в команде INSERT.

В настоящее время он выступает как: ... Отметки ) VALUES VALUES ($name,...

Удалите второе вхождение Ценностей и посмотреть, если он работает. Он никогда не выдавал сообщение об ошибке?

+0

О, я думаю, что случайно случайно каким-то образом скопировал еще один «ЦЕННОСТИ», когда я помещал код в сообщение, что на самом деле не является кодом, который я тестирую (так что не вызывает проблема). Я удалил его с поста – mbecker73

+2

Ahh, ладно. Возможно, вам нужно будет добавить одинарные кавычки до и после переменных, если только это не число. Например: VALUES ('$ name', '$ value', '$ event', '$ timestamp') Я не считаю, что поплавки должны быть процитированы, но проверяйте их и удалите цитаты вокруг них, если они нет. –

+0

Да, я пробовал это (и просто повторил его), но безуспешно. – mbecker73

1

Я думаю, что ваш синтаксис SQL неверен. Посмотрите на этой линии:

mysqli_query($con,"INSERT INTO `Driving Data`(`Name`, `Value`, `Event`, `Timestamp`) VALUES ($name, $value, $event, $timestamp)"); 

Если какой-либо переменной ($ имя, например) имеет пробелы, ваш SQL будет выглядеть следующим образом:

INSERT INTO `Driving Data`(`Name`, `Value`, `Event`, `Timestamp`) VALUES (Name with spaces, ...) 

, но это должно быть между одинарными кавычками:

INSERT INTO `Driving Data`(`Name`, `Value`, `Event`, `Timestamp`) VALUES ('Name with spaces', ...) 

Я не тестировал это, но я думаю, что это источник вашей проблемы. Я предполагаю, что это строка ошибки, потому что, как вы говорите, создается текстовый файл (так что файл_put_contents перед запуском работает нормально).

Кроме того, почему вы не используете какой-либо идентификатор для вставленных строк? Я бы добавил в качестве первичного ключа автоматически увеличивающийся столбец «id».

+0

Вы можете использовать if (! mysqli_query ($ con, ...)) die ("Ошибка SQL: msgstr "mysqli_error ($ con)); для проверки ошибок SQL –

Смежные вопросы