Каждый раз, когда вы получаете ...
"Warning: mysqli_fetch_object () ожидает, что параметр 1 будет mysqli_result, boolean задан«
blockquote>... это, вероятно, из-за проблемы с вашим запросом.
prepare()
илиquery()
могут возвращатьFALSE
(логическое), но это общее сообщение об отказе не оставляет вас в стороне от подсказок. Как вы узнаете, что не так с вашим запросом? Вы задаете !Прежде всего убедитесь, что сообщения об ошибках включены и видны: добавьте эти две строки в начало файла (ов) сразу после открытия
<?php
:error_reporting(E_ALL); ini_set('display_errors', 1);
Если ваше сообщение об ошибках установлено в php.ini, вам не придется беспокоиться об этом. Просто убедитесь, что вы обрабатываете ошибки изящно и никогда не раскрываете истинные причины каких-либо проблем для ваших пользователей. Выявление истинной причины для общественности может быть приглашением на золото с гравировкой для тех, кто хочет нанести вред вашим сайтам и серверам. Если вы не хотите отправлять ошибки в браузер, вы всегда можете следить за журналами ошибок веб-сервера. Расположение журналов будет варьироваться от сервера к серверу, например, на Ubuntu журнал ошибок обычно находится в
/var/log/apache2/error.log
. Если вы изучаете журналы ошибок в среде Linux, вы можете использоватьtail -f /path/to/log
в окне консоли, чтобы видеть ошибки, когда они происходят в режиме реального времени .... или как вы их делаете.Как только вы 'squared away на стандартном сообщении об ошибках, добавляющем проверку ошибок в вашем соединении с базой данных, и запросы дадут вам гораздо более подробную информацию о проблемах. Посмотрите на этот пример, где имя столбца неверно. Во-первых, код, возвращающий роковое сообщение об ошибке:
$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?"; $query = $mysqli->prepare($sql)); // assuming $mysqli is the connection $query->bind_param('s', $definition); $query->execute();
Ошибка является общей и не очень помогает вам в решении того, что происходит.
С помощью пары больше строк кода вы можете получить очень подробную информацию, которую вы можете использовать для решения проблемы сразу . Проверьте утверждение
prepare()
для правдивости, и если это хорошо, вы можете перейти к привязке и исполнению.$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?"; if($query = $mysqli->prepare($sql)) { // assuming $mysqli is the connection $query->bind_param('s', $definition); $query->execute(); // any additional code you need would go here. } else { $error = $mysqli->errno . ' ' . $mysqli->error; echo $error; // 1054 Unknown column 'foo' in 'field list' }
Если что-то не так, вы можете выплюнуть сообщение об ошибке, которое приведет вас к проблеме , В этом случае в таблице нет столбца
foo
, решение проблемы тривиально.Если вы выберете, вы можете включить эту проверку в функцию или класс и расширить ее, обработав ошибки изящно, как упомянутых ранее.
Вы не можете иметь mutliple @Path
аннотации по одному методу. Это приводит к синтаксической ошибке «дублирования аннотации».
Однако существует несколько способов эффективного сопоставления двух путей к методу.
Аннотации @Path
в JAX-RS принимают параметры, значения которых могут быть ограничены с помощью регулярных выражений.
Эта аннотация :
@Path("a/{parameter: path1|path2}")
позволит получить доступ к методу запросов как для /a/path1
, так и для /a/path2
. Если вам нужно работать с подпакетами, выполните слэши: {a:path1\\/subPath1|path2\\/subPath2}
В качестве альтернативы вы можете настроить перенаправление. Вот как это сделать в Джерси (эталонная реализация JAX-RS), путем определения другого субресурса. Это просто пример, если вы предпочитаете другой способ обработки перенаправления, не стесняйтесь использовать его.
@Path("basepath")
public class YourBaseResource {
//this gets injected after the class is instantiated by Jersey
@Context
UriInfo uriInfo;
@Path("a/b")
@GET
public Responce method1(){
return Response.ok("blah blah").build();
}
@Path("a/b/c")
@GET
public Response method2(){
UriBuilder addressBuilder = uriInfo.getBaseUriBuilder();
addressBuilder.path("a/b");
return Response.seeOther(addressBuilder.build()).build();
}
}
Если вы часто требуется такая функциональность, я предлагаю перехватить входящие запросы с использованием фильтра сервлета и переписать пути «на лету». Это должно помочь вам сохранить все перенаправления в одном месте. В идеале вы можете использовать готовую библиотеку. UrlRewriteFilter
может сделать трюк, если у вас все в порядке с лицензией BSD (подробности см. на сайте своего кодового сайта Google).
Другой вариант - обработать это с помощью прокси-сервер, настроенный перед вашим Java-приложением. Вы можете настроить сервер Apache, чтобы предлагать базовые правила кэширования и перезаписи без усложнения кода Java.
Как объяснено в ответе Тома , вы не можете использовать более одного аннотации @Path
для одного метода, потому что во время компиляции вы будете работать error: duplicate annotation
.
Я думаю, что самый простой способ обойти это - использовать перегрузку метода:
@Path("{foo}")
public Response rest(@PathParam("foo") final String foo) {
return this.rest(foo, "");
}
@Path("{foo}/{bar}")
public Response rest(@PathParam("foo") final String foo,
@PathParam("bar") final String bar) {
return Response.ok(foo + " " + bar).build();
}
Вы также можете использовать более разные имена методов, если вы столкнетесь с тем, что несколько перегруженных методов имеют подпись.
Другое решение для вашего конкретного примера:
Предположим, что:
/a
для класса ресурсов /b/c
и /b
- пути для методов , поскольку полный путь выглядит следующим образом:
<protocol><host><port><app><url-pattern><resource-path><method-path>
.
Используйте необязательный параметр
@Path("/b{c : (/c)?}")
public Response searchNames(@PathParam("c") String val) {
...
}
Пример выше работает для всех примеров, таких как:
/b
/b/
/b/c
/b/c/
, но если c
предоставлен, val
- /c
(перед ним есть /
).
Если вы хотите решить проблему выше (чтобы избежать разбора Java), вам нужно что-то более сложное:
@Path("/b{slash : (/)?}{c:((?<=/).*)?}")
, который вернет только c
(не /c
) для 3-я маркерная точка, но для четвертой маркерной точки она вернет c/
, которая должна быть проанализирована на Java.
Но для вашего случая ( "выполненный метод один и тот же" ), не беспокойтесь о разборе, потому что у вас нет разных действий.