/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2008 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| [email protected] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Antony Dovgal <tony at daylessday.org> |
| Based on Sphinx PHP API by Andrew Aksyonoff <shodan at shodan.ru> |
+----------------------------------------------------------------------+
*/
/* $Id: sphinx.c 303462 2010-09-17 12:08:47Z santiago $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "ext/standard/file.h"
#include "zend_operators.h"
#include "php_sphinx.h"
#include <sphinxclient.h>
static zend_class_entry *ce_sphinx_client;
static zend_object_handlers php_sphinx_client_handlers;
static zend_object_handlers cannot_be_cloned;
typedef struct _php_sphinx_client {
zend_object std;
sphinx_client *sphinx;
zend_bool array_result;
} php_sphinx_client;
#ifdef COMPILE_DL_SPHINX
ZEND_GET_MODULE(sphinx)
#endif
#ifndef E_RECOVERABLE_ERROR
#define E_RECOVERABLE_ERROR E_WARNING
#endif
#define SPHINX_CONST(name) REGISTER_LONG_CONSTANT(#name, name, CONST_CS | CONST_PERSISTENT)
#define SPHINX_INITIALIZED(c) \
if (!(c) || !(c)->sphinx) { \
php_error_docref(NULL TSRMLS_CC, E_WARNING, "using uninitialized SphinxClient object"); \
RETURN_FALSE; \
}
static void php_sphinx_client_obj_dtor(void *object TSRMLS_DC) /* {{{ */
{
php_sphinx_client *c = (php_sphinx_client *)object;
sphinx_destroy(c->sphinx);
zend_object_std_dtor(&c->std TSRMLS_CC);
efree(c);
}
/* }}} */
static zend_object_value php_sphinx_client_new(zend_class_entry *ce TSRMLS_DC) /* {{{ */
{
php_sphinx_client *c;
zend_object_value retval;
c = ecalloc(1, sizeof(*c));
zend_object_std_init(&c->std, ce TSRMLS_CC);
retval.handle = zend_objects_store_put(c, (zend_objects_store_dtor_t)zend_objects_destroy_object, php_sphinx_client_obj_dtor, NULL TSRMLS_CC);
retval.handlers = &php_sphinx_client_handlers;
return retval;
}
/* }}} */
static zval *php_sphinx_client_read_property(zval *object, zval *member, int type TSRMLS_DC) /* {{{ */
{
php_sphinx_client *c;
zval tmp_member;
zval *retval;
zend_object_handlers *std_hnd;
c = (php_sphinx_client *)zend_object_store_get_object(object TSRMLS_CC);
if (member->type != IS_STRING) {
tmp_member = *member;
zval_copy_ctor(&tmp_member);
convert_to_string(&tmp_member);
member = &tmp_member;
}
/* XXX we can either create retval ourselves (for custom properties) or use standard handlers */
std_hnd = zend_get_std_object_handlers();
retval = std_hnd->read_property(object, member, type TSRMLS_CC);
if (member == &tmp_member) {
zval_dtor(member);
}
return retval;
}
/* }}} */
static HashTable *php_sphinx_client_get_properties(zval *object TSRMLS_DC) /* {{{ */
{
php_sphinx_client *c;
const char *warning, *error;
zval *tmp;
c = (php_sphinx_client *)zend_objects_get_address(object TSRMLS_CC);
error = sphinx_error(c->sphinx);
MAKE_STD_ZVAL(tmp);
ZVAL_STRING(tmp, (char *)error, 1);
zend_hash_update(c->std.properties, "error", sizeof("error"), (void *)&tmp, sizeof(zval *), NULL);
warning = sphinx_warning(c->sphinx);
MAKE_STD_ZVAL(tmp);
ZVAL_STRING(tmp, (char *)warning, 1);
zend_hash_update(c->std.properties, "warning", sizeof("warning"), (void *)&tmp, sizeof(zval *), NULL);
return c->std.properties;
}
/* }}} */
#ifdef TONY_200807015
static inline void php_sphinx_error(php_sphinx_client *c TSRMLS_DC) /* {{{ */
{
const char *err;
err = sphinx_error(c->sphinx);
if (!err || err[0] == '\0') {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown error");
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", err);
}
}
/* }}} */
#endif
static void php_sphinx_result_to_array(php_sphinx_client *c, sphinx_result *result, zval **array TSRMLS_DC) /* {{{ */
{
zval *tmp, *tmp_element, *sub_element, *sub_sub_element;
int i, j;
array_init(*array);
/* error */
if (!result->error) {
add_assoc_string_ex(*array, "error", sizeof("error"), "", 1);
} else {
add_assoc_string_ex(*array, "error", sizeof("error"), (char *)(result->error), 1);
}
/* warning */
if (!result->warning) {
add_assoc_string_ex(*array, "warning", sizeof("warning"), "", 1);
} else {
add_assoc_string_ex(*array, "warning", sizeof("warning"), (char *)result->warning, 1);
}
/* status */
add_assoc_long_ex(*array, "status", sizeof("status"), result->status);
switch(result->status) {
case SEARCHD_OK:
/* ok, continue reading data */
break;
case SEARCHD_WARNING:
/* this seems to be safe, too */
break;
default:
/* libsphinxclient doesn't nullify the data
in case of error, so it's not safe to continue. */
return;
}
/* fields */
MAKE_STD_ZVAL(tmp);
array_init(tmp);
for (i = 0; i < result->num_fields; i++) {
add_next_index_string(tmp, result->fields[i], 1);
}
add_assoc_zval_ex(*array, "fields", sizeof("fields"), tmp);
/* attrs */
MAKE_STD_ZVAL(tmp);
array_init(tmp);
for (i = 0; i < result->num_attrs; i++) {
#if SIZEOF_LONG == 8
add_assoc_long_ex(tmp, result->attr_names[i], strlen(result->attr_names[i]) + 1, result->attr_types[i]);
#else
double float_value;
char buf[128];
float_value = (double)result->attr_types[i];
slprintf(buf, sizeof(buf), "%.0f", float_value);
add_assoc_string_ex(tmp, result->attr_names[i], strlen(result->attr_names[i]) + 1, buf, 1);
#endif
}
add_assoc_zval_ex(*array, "attrs", sizeof("attrs"), tmp);
/* matches */
if (result->num_matches) {
MAKE_STD_ZVAL(tmp);
array_init(tmp);
for (i = 0; i < result->num_matches; i++) {
MAKE_STD_ZVAL(tmp_element);
array_init(tmp_element);
if (c->array_result) {
/* id */
#if SIZEOF_LONG == 8
add_assoc_long_ex(tmp_element, "id", sizeof("id"), sphinx_get_id(result, i));
#else
double float_id;
char buf[128];
float_id = (double)sphinx_get_id(result, i);
slprintf(buf, sizeof(buf), "%.0f", float_id);
add_assoc_string_ex(tmp_element, "id", sizeof("id"), buf, 1);
#endif
}
/* weight */
add_assoc_long_ex(tmp_element, "weight", sizeof("weight"), sphinx_get_weight(result, i));
/* attrs */
MAKE_STD_ZVAL(sub_element);
array_init(sub_element);
for (j = 0; j < result->num_attrs; j++) {
double float_value;
char buf[128];
MAKE_STD_ZVAL(sub_sub_element);
switch(result->attr_types[j]) {
case SPH_ATTR_MULTI | SPH_ATTR_INTEGER:
{
int k;
unsigned int *mva = sphinx_get_mva(result, i, j);
unsigned int tmp, num;
array_init(sub_sub_element);
if (!mva) {
break;
}
memcpy(&num, mva, sizeof(unsigned int));
for (k = 1; k <= num; k++) {
mva++;
memcpy(&tmp, mva, sizeof(unsigned int));
#if SIZEOF_LONG == 8
add_next_index_long(sub_sub_element, tmp);
#else
float_value = (double)tmp;
slprintf(buf, sizeof(buf), "%.0f", float_value);
add_next_index_string(sub_sub_element, buf, 1);
#endif
}
} break;
case SPH_ATTR_FLOAT:
ZVAL_DOUBLE(sub_sub_element, sphinx_get_float(result, i, j));
break;
#if LIBSPHINX_VERSION_ID >= 110
case SPH_ATTR_
sphinx开源的搜索引擎的PHP模块扩展包(linux) sphinx.1.1.0版本
需积分: 1 154 浏览量
2024-04-30
19:19:18
上传
评论
收藏 13KB GZ 举报
林戈的IT生涯
- 粉丝: 3885
- 资源: 43